将动态数组传递给C中的函数

Tom*_*Tom 6 c arrays function realloc

我正在尝试创建一个函数,该函数将数组作为参数,向其添加值(如果需要,增加其大小)并返回项的计数.到目前为止,我有:

int main(int argc, char** argv) {
    int mSize = 10;
    ent a[mSize];
    int n;
    n = addValues(a,mSize);

    for(i=0;i<n;i++) {
       //Print values from a
    }
}

int addValues(ent *a, int mSize) {
    int size = mSize;

    i = 0;

    while(....) { //Loop to add items to array
        if(i>=size-1) { 
            size = size*2;
            a = realloc(a, (size)*sizeof(ent));
        }
        //Add to array
        i++;
    }
    return i;
}
Run Code Online (Sandbox Code Playgroud)

如果mSize足够大以容纳数组的所有潜在元素,则此方法有效,但如果需要调整大小,则会出现分段错误.

我也尝试过:

int main(int argc, char** argv) {
    ...
    ent *a;
    ...
}

int addValues(ent *a, int mSize) {
    ...
    a = calloc(1, sizeof(ent);
    //usual loop
    ...
}
Run Code Online (Sandbox Code Playgroud)

无济于事.

我认为这是因为当我调用realloc时,'a'的副本指向别处 - 如何修改它以使'a'始终指向同一位置?

我正确地谈到这个吗?有没有更好的方法来处理C中的动态结构?我应该实施链接列表来处理这些吗?

Tod*_*lin 11

这里的主要问题是你正在尝试将realloc与堆栈分配的数组一起使用.你有:

ent a[mSize];
Run Code Online (Sandbox Code Playgroud)

这是堆栈上的自动分配.如果你想在以后使用realloc(),你可以使用malloc()在堆上创建数组,如下所示:

ent *a = (ent*)malloc(mSize * sizeof(ent));
Run Code Online (Sandbox Code Playgroud)

这样malloc库(以及realloc()等)知道你的数组.从外观上看,您可能会将C99可变长度数组与真正的动态数组混淆,因此在尝试修复此问题之前,请务必了解其中的差异.

但实际上,如果您在C中编写动态数组,则应尝试使用OOP-ish设计来封装有关数组的信息并将其隐藏在用户之外.您希望将有关数组的信息(例如指针和大小)合并到结构和操作(例如,分配,添加元素,删除元素,释放等)到与​​结构一起使用的特殊函数中.所以你可能有:

typedef struct dynarray {
   elt *data;
   int size;
} dynarray;
Run Code Online (Sandbox Code Playgroud)

您可以定义一些函数来使用dynarrays:

// malloc a dynarray and its data and returns a pointer to the dynarray    
dynarray *dynarray_create();     

// add an element to dynarray and adjust its size if necessary
void dynarray_add_elt(dynarray *arr, elt value);

// return a particular element in the dynarray
elt dynarray_get_elt(dynarray *arr, int index);

// free the dynarray and its data.
void dynarray_free(dynarray *arr);
Run Code Online (Sandbox Code Playgroud)

这样,用户无需准确记住如何分配内容或当前数组的大小.希望能让你开始.


xah*_*tep 6

尝试重新处理它,以便传入指向数组指针的指针,即ent **a.然后,您将能够在阵列的新位置更新调用者.