简体   繁体   English

C中的动态数组和指针

[英]dynamic array and pointer in C

I'm a beginner in C and programming. 我是C和编程的初学者。 I would like to ask some questions on dynamic array and pointer in C. 我想问一些关于动态数组和C语言中指针的问题。
I am trying to create a dynamic array and increase its capacity, but I can't get my code working. 我试图创建一个动态数组并增加其容量,但是我无法使我的代码正常工作。 I believe something is wrong in my setCapacityDynArr function. 我相信setCapacityDynArr函数setCapacityDynArr

Can someone give me some help? 有人可以给我些帮助吗? Thanks! 谢谢!

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;
}
 //pointer is changed to reference the new array v = new_v; 

This is your problem, a classic mistake in C. In fact the function changes its own copy of the pointer, the caller never sees the change. 这是您的问题,这是C语言中的经典错误。实际上,函数更改了自己的指针副本,而调用者却看不到更改。 The problem is amply described by this C FAQ . C FAQ已充分描述了该问题

I suggest a different approach. 我建议使用另一种方法。 There's no reason to make a new v : you simply want more storage associated with it. 没有理由创建一个新的v您只需要更多与之关联的存储 So instead of actually changing v , you'll probably want to just call realloc on the storage: v->DATA . 因此,除了实际更改v ,您可能只想在存储设备上调用reallocv->DATA

You might get away with something like: 您可能会遇到类似这样的情况:

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

v->data = tmp;

And this way you don't need to copy the elements either: realloc takes care of that. 这样,您也不需要复制任何元素: realloc会解决这个问题。

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

Your original pointer outside the function is not changed, since you passed the value of the pointer not the address of it here: 函数外的原始指针不会更改,因为您在此处传递了指针值而不是其地址

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

Yes it's an error in _setCapacityDynArr . 是的,这是_setCapacityDynArr的错误。 It's an error because you declare an DynArr structure on the stack, then you try to free it and assign a new pointer to it. 这是一个错误,因为您在堆栈上声明了DynArr结构,然后尝试free该结构并为其分配新的指针。 That will not work, as items allocated on the stack can't be freed. 这将不起作用,因为无法释放在堆栈上分配的项目。

What you want to do is to reallocate only the actual data, not the whole structure. 您要做的是仅重新分配实际数据,而不是整个结构。 For this you should use the realloc function. 为此,您应该使用realloc函数。

There are other problems with the function as well, like you assigning to the pointer. 该函数还存在其他问题,例如您分配给指针。 This pointer is a local variable so when the function returns all changes to it will be lost. 该指针是一个局部变量,因此当函数返回所有对其的更改时,它将丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM