2012-07-10 59 views
4

免責聲明:這是作業。我正在嘗試它,不要期望或希望任何人爲我做這件事。只是幾個指針(嘿嘿),我會錯誤的將不勝感激。realloc無效的舊尺寸

作業要求我創建一個包含10個元素的int*數組,然後嘗試向其中插入一百萬個int。每個插入檢查數組是否需要調整大小,如果是這樣,我增加它的大小,以便它可以保存一個元素。

當我插入10,000個元素,它工作正常,但如果我嘗試100000元,我得到以下錯誤:

*** glibc detected *** ./set2: realloc(): invalid old size: 0x00000000024dc010 *** 

這是我運行的代碼。我評論過它,因此它易於閱讀。

void main() 
{ 
    //begin with a size of 10 
    int currentsize = 10; 
    int* arr = malloc(currentsize * sizeof(int));  
    int i; 

    //initalize with all elements set to INT_MAX 
    for(i = 0; i < currentsize; i++) { 
     arr[i] = INT_MAX; 
    } 


    // insert random elements 
    for(i = 0; i < 100000; i++) { 
     currentsize = add(rand() % 100,arr,currentsize); 
    } 

    free(arr); 
} 

/* 
    Method resizes array if needed, and returns the new size of the array 
    Also inserts the element into the array 
*/ 
int add(int x, int* arr, int size) 
{ 
    //find the first available location 
    int newSize = size; 
    int i; 
    for(i = 0; i < size; i++) { 
     if (arr[i] == INT_MAX) 
      break; 
    } 

    if (i >= size) { 
     //need to realloc 
     newSize++; 
     arr = realloc(arr, newSize * sizeof(int));  
    } 

    arr[i] = x; 

    return newSize; 
} 

回答

5

的錯誤可能是因爲你正確使用的realloc的功能add改變arr,但是這個修改後的值時丟失add回報。所以下一次撥打電話add將會收到舊的,現在不好的價值。

另外我不明白你爲什麼使用for循環來搜索。你知道你想添加最後一個元素,爲什麼搜索?只需重新分配陣列並在新插槽中插入新值即可。

順便說一句,我很確定你的老師試圖讓你看到,爲每個成員重新分配導致一個漸近運行時間問題。大多數realloc的實現將使用該算法進行拷貝lot。這就是爲什麼真正的程序將陣列大小增加因子大於1(通常爲1.5或2),而不是固定的數量。

通常的習慣用法是抽象的可變尺寸陣列中的結構:

typedef struct array_s { 
    int *elts; 
    int size; 
} VARIABLE_ARRAY; 

void init(VARIABLE_ARRAY *a) 
{ 
    a->size = 10; 
    a->elts = malloc(a->size * sizeof a->elts[0]); 
    // CHECK FOR NULL RETURN FROM malloc() HERE 
} 

void ensure_size(VARIABLE_ARRAY *a, size_t size) 
{ 
    if (a->size < size) { 

    // RESET size HERE TO INCREASE BY FACTOR OF OLD SIZE 
    // size = 2 * a->size; 

    a->elts = realloc(size * sizeof a->elts[0]); 
    a->size = size; 

    // CHECK FOR NULL RETURN FROM realloc() HERE 
    } 
} 

// Set the i'th position of array a. If there wasn't 
// enough space, expand the array so there is. 
void set(VARIABLE_ARRAY *a, int i, int val) 
{ 
    ensure_size(a, i + 1); 
    a->elts[i] = val; 
} 

void test(void) 
{ 
    VARIABLE_ARRAY a; 

    init(&a); 

    for (int i = 0; i < 100000; i++) { 
    set(&a, i, rand()); 
    } 

    ... 

} 
+0

應該添加接收'int **'不會導致此問題? – xbonez 2012-07-10 03:54:18

+0

是的使用'int **' – Hogan 2012-07-10 03:55:43

+1

是的,你說你不想要答案,我尊重這一點。你是對的。 – Gene 2012-07-10 03:58:36

1

我會通過arradd()作爲指針(的指針),以便它可以的add()

內進行修改
int add(int x, int** arr, int size) 
{ 
    // ... 
    *arr = realloc(*arr, newSize * sizeof(int)); 
} 

,把它....

currentsize = add(rand() % 100, &arr, currentsize); 

請注意,您的代碼(和我建議的更改)沒有進行任何錯誤檢查。您應該檢查mallocrealloc的返回值NULL