如何在 C 函数中 return `realloc` 数组

How to return a `realloc` array in C function

我想将数字附加到一个空数组,这些数字的数量一开始是未知的。比如生成1到10的数字,然后一个接一个的追加。

generateFromOneToTen 会将我的结果保存在 output 中,执​​行后 count 应该是 10。如果我在此函数中打印结果,一切都很好。

int generateFromOneToTen(int *output, int count)
{
    for (int i = 0; i < 10; i++) {
        output = arrayAppendInt(output, i + 1, count);
        count++;
    }

    // Print result of `output` is 1,2,3...10 here

    return count;
}

我实现了 arrayAppendInt 以动态增加数组的长度并在旧值之后附加新值。

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

问题来了。调用生成函数时,numbers 将始终为 NULL。我怎样才能 return 生成的数字到 numbers 变量?

int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(numbers, 0);
                             ^^^^^^^

您可以使用指向整数指针的指针 (int **):

int generateFromOneToTen(int **output, int count)
{
    for (int i = 0; i < 10; i++) {
        *output = arrayAppendInt(*output, i + 1, count);
        count++;
    }
    // `*output` is 1,2,3...10 here
    return count;
}

您可以像这样重写 arrayAppendInt 函数:

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray;
    if (array==NULL)
      newArray = (int*) malloc ((1+size) * sizeof(int));
    else
      newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

然后这样称呼它 *output = arrayAppendInt(*output, i + 1, i);

最干净的解决方案是(在我看来)将数组+簿记(大小,使用)打包成一个结构,并使用(指向)这个结构作为参数。


#include <stdlib.h>

struct dopedarray {
        unsigned size;
        unsigned used;
        int *array;
        };

现在您可以将所有分配和簿记内容放入一个函数中(可以内联):


int array_resize(struct dopedarray *ap, unsigned newsize)
{
int *newp;

if(!ap) return -1;

newp = realloc (ap->array, newsize*sizeof*ap->array);
  // check return value here...
if (!newp) return -1;

free(ap->array);
ap->array = newp;
ap->size = newsize;

  // bookkeeping sanity
if(ap->size > ap->used ) { ap->used > ap->size; }

return 0;
}

add_element函数也需要稍微改动一下:


int array_add_element(struct dopedarray *ap, int value)
{
if(ap->used >= ap->size){
        unsigned newsz;
        newsz= ap->used ? 2*ap->used: 4;
        array_resize(ap, newsz);
        // check return value here...
        }

ap->array[ap->used++] = val;
return 0;
}

我的问题的完整代码:

int generateFromOneToTen(int **output, int count) // +
{
    for (int i = 0; i < 10; i++) {
        *output = arrayAppendInt(*output, i + 1, count); // ++
        count++;
    }

    return count;
}

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(&numbers, 0); // +

这个答案也值得一读: