繁体   English   中英

C中的动态数组和指针

[英]dynamic array and pointer in C

我是C和编程的初学者。 我想问一些关于动态数组和C语言中指针的问题。
我试图创建一个动态数组并增加其容量,但是我无法使我的代码正常工作。 我相信setCapacityDynArr函数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;
}
 //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会解决这个问题。

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

函数外的原始指针不会更改,因为您在此处传递了指针值而不是其地址

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

是的,这是_setCapacityDynArr的错误。 这是一个错误,因为您在堆栈上声明了DynArr结构,然后尝试free该结构并为其分配新的指针。 这将不起作用,因为无法释放在堆栈上分配的项目。

您要做的是仅重新分配实际数据,而不是整个结构。 为此,您应该使用realloc函数。

该函数还存在其他问题,例如您分配给指针。 该指针是一个局部变量,因此当函数返回所有对其的更改时,它将丢失。

暂无
暂无

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

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