2013-04-12 98 views
1

我是C和編程的初學者。我想問一些關於動態數組和C中指針的問題。我試圖創建一個動態數組並增加其容量,但是我無法讓我的代碼工作。我相信我的setCapacityDynArr功能有問題。動態數組和指針C

有人可以給我一些幫助嗎? 謝謝!

struct DynArr { 
    TYPE *data; /* pointer to the data array */ 
    int size; /* Number of elements in the array */ 
    int capacity; /* capacity ofthe array */ 
}; 

void initDynArr(struct DynArr *v, int capacity) { 
    v->data = malloc(sizeof(TYPE) * capacity); 
    assert(v->data != 0); 
    v->size = 0; 
    v->capacity = capacity; 
} 

void freeDynArr(struct DynArr *v) { 
    if (v->data != 0) { 
     free(v->data); /* free the space on the heap */ 
     v->data = 0; /* make it point to null */ 
    } 
    v->size = 0; 
    v->capacity = 0; 
} 

int sizeDynArr(struct DynArr *v) { 
    return v->size; 
} 

void addDynArr(struct DynArr *v, TYPE val) { 
    /* Check to see if a resize is necessary */ 
    if (v->size >= v->capacity) { 
     _setCapacityDynArr(v, 2 * v->capacity); 
    } 
    v->data[v->size] = val; 
    v->size++; 
} 

void _setCapacityDynArr(struct DynArr *v, int newCap) { 
    //create a new array 
    struct DynArr *new_v; 
    assert(newCap > 0); 
    new_v = malloc(newCap * sizeof(struct DynArr)); 
    assert(new_v != 0); 
    initDynArr(new_v, newCap); 

    //copy old values into the new array 
    for (int i = 0; i < new_v->capacity; i++) { 
     new_v->data[i] = v->data[i]; 
    } 

    //free the old memory 
    freeDynArr(v); 

    //pointer is changed to reference the new array 
    v = new_v; 

} 

int main(int argc, const char * argv[]) { 

    //Initialize an array 
    struct DynArr myArray; 
    initDynArr(&myArray, 5); 
    printf("size = 0, return: %d\n", myArray.size); 
    printf("capacity = 5, return: %d\n", myArray.capacity); 

    //Add value to the array 
    addDynArr(&myArray, 10); 
    addDynArr(&myArray, 11); 
    addDynArr(&myArray, 12); 
    addDynArr(&myArray, 13); 
    addDynArr(&myArray, 14); 
    addDynArr(&myArray, 15); 

    for (int i = 0; i < myArray.size; i++) { 
     printf("myArray value - return: %d\n", myArray.data[i]); 
    } 

    return 0; 
} 
+2

它在哪裏失敗?它顯示了什麼錯誤? – sashkello

+0

是的。如果有人想調試你的程序,你可能會感到幸運,但爲了得到很好的答案,你應該描述它是如何失敗的。 –

回答

5
//pointer is changed to reference the new array 
v = new_v; 

這是你的問題,C中的經典錯誤其實功能改變自己的指針的副本,調用者永遠看不到的變化。這個問題由C FAQ充分描述。

我建議採用不同的方法。沒有理由製作新的v,您只需要更多與其關聯的存儲。因此,您可能不想實際更改v,而只需在存儲上撥打reallocv->DATA

tmp = realloc(v->data, newCap * sizeof *v->data); 
if (!tmp) 
    error; 

v->data = tmp; 

而這樣一來,你就不需要複製的元素之一::realloc需要的是照顧

你可能會喜歡的東西離開。

+1

對於使用tmp指針正確使用realloc()的情況。 –

+0

謝謝大家的提示! – user2203774

1
//pointer is changed to reference the new array 
v = new_v; 

你原來的功能外指針改變,因爲你通過了值指針的這裏的地址:

void _setCapacityDynArr(struct DynArr *v, int newCap) 
{ 
1

是的,這是一個錯誤_setCapacityDynArr。這是一個錯誤,因爲您在堆棧中聲明瞭DynArr結構,然後嘗試free併爲其分配新的指針。這是行不通的,因爲在堆棧上分配的項目不能被釋放。

你想要做的是隻重新分配實際數據,而不是整個結構。爲此,您應該使用realloc功能。

該函數還有其他問題,例如您指定給指針。這個指針是一個局部變量所以當函數返回時它的所有修改都會丟失。