我是C和编程的初学者。我想问一下关于C.中动态数组和指针的一些问题
我正在尝试创建一个动态数组并增加其容量,但我不能让我的代码工作。我认为我的setCapacityDynArr
函数出了问题。
有人可以给我一些帮助吗? 谢谢!
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;
}
答案 0 :(得分:5)
//pointer is changed to reference the new array v = new_v;
这是你的问题,是C中的经典错误。事实上,该函数更改了自己的指针副本,调用者永远不会看到更改。这个C FAQ充分描述了这个问题。
我建议采用不同的方法。没有理由建立一个新的v
:您只需要更多存储空间。因此,您可能只想在存储空间v
上调用realloc
,而不是实际更改v->DATA
。
你可能会逃避:
tmp = realloc(v->data, newCap * sizeof *v->data);
if (!tmp)
error;
v->data = tmp;
这样你就不需要复制元素了:realloc
负责处理。
答案 1 :(得分:1)
//pointer is changed to reference the new array
v = new_v;
您在函数外部的原始指针未已更改,因为您在此处传递了指针的值而不是其地址:< / p>
void _setCapacityDynArr(struct DynArr *v, int newCap)
{
答案 2 :(得分:1)
是的,这是_setCapacityDynArr
中的错误。这是一个错误,因为您在堆栈上声明了DynArr
结构,然后尝试free
它并为其分配一个新指针。这不起作用,因为无法释放在堆栈上分配的项目。
您要做的是仅重新分配实际数据,而不是整个结构。为此,您应该使用realloc
函数。
该功能还存在其他问题,例如您指定指针。这个指针是一个局部变量,所以当函数返回时,它的所有更改都将丢失。