【问题标题】:How to return a `realloc` array in C function如何在 C 函数中返回“realloc”数组
【发布时间】:2018-05-10 09:05:29
【问题描述】:

我想将数字附加到一个空数组中,而这些数字的数量在一开始是未知的。例如,生成从 1 到 10 的数字并一个接一个地追加。

generateFromOneToTen 将我的结果保存在outputcount 在执行后应该是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。如何将生成的数字返回到numbers 变量?

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

【问题讨论】:

  • man realloc():: ... if ptr is NULL, then the call is equivalent to malloc(size), for all values of size;...
  • 所以要修改函数的参数numbersPossible duplicate?
  • 最干净的解决方案是恕我直言,将数组+簿记(大小,使用)打包成一个结构,并使用(指向)这个结构的指针作为参数。

标签: c arrays pointers realloc


【解决方案1】:

您可以使用指向整数指针 (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);

【讨论】:

  • 那么arrayAppendInt怎么修改呢?
  • 我更新了我的答案,修改了arrayAppendInt。这是我的答案的完整综合:taas.trust-in-soft.com/tsnippet/t/856bfc98
  • 我认为我不需要更改arrayAppendInt
  • 同意,其实不用改!
  • if (array==NULL) newArray = (int*) malloc ((1+size) * sizeof(int)); 你不需要特殊情况。 (你也不需要演员)
【解决方案2】:

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


#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;
}

【讨论】:

    【解决方案3】:

    我的问题的完整代码:

    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); // +
    

    这个答案也值得一读:https://stackoverflow.com/a/9459803/1951254

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 2012-06-17
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2012-09-26
      相关资源
      最近更新 更多