用于在C中的其他函数中分配数组的函数

时间:2015-08-06 18:56:20

标签: c arrays pointers compound-literals

使用函数在另一个函数中分配数组时遇到问题。以下是导致问题的细分:

void
array_allocator(int method, int** a, int** b){
  if (method == 0)
  {
    (*a) = (int[5]) {0, 1, 2, 3, 4};
    (*b) = (int[5]) {5, 6, 7, 8, 9};

    printf ("in array_allocator\n");
    printf ("a = (%d, %d, %d, %d, %d)\n",(*a)[0],(*a)[1],(*a)[2],(*a)[3],(*a)[4]);
    printf ("b = (%d, %d, %d, %d, %d)\n",(*b)[0],(*b)[1],(*b)[2],(*b)[3],(*b)[4]);
  }
  else printf("unknown method\n");
}

void
some_function (int method){
  int *a, *b;

  array_allocator(method, &a, &b);

  printf ("in some_function\n");
  printf ("a = (%d, %d, %d, %d, %d)\n",a[0],a[1],a[2],a[3],a[4]);
  printf ("b = (%d, %d, %d, %d, %d)\n",b[0],b[1],b[2],b[3],b[4]);
}

int main()
{
  int method = 0;
  some_function(method);
  return 0;
}

用gcc编译并执行后得到输出:

in array_allocator
a = (0, 1, 2, 3, 4)
b = (5, 6, 7, 8, 9)
in some_function
a = (10, 0, 4196346, 0, 1448083200)
b = (-730692608, 32637, 16, 0, 4196346)

不知何故,数组分配后的值变得随机,如果我在printf()打印数组值之前添加一些some_function()函数,甚至会更改。

4 个答案:

答案 0 :(得分:2)

array_allocator()函数中,您使用的是复合文字。

关于复合文字的用法,引用C11标准,章节§6.5.2.5,(强调我的

  

[...]如果复合文字出现在函数体外,则该对象具有静态存储持续时间; 否则,它具有与封闭块相关联的自动存储持续时间。

因此,一旦函数返回,复合文字就不再存在了。因此,a中的some_function()取消引用又是UB。

解决方案:您可能希望通过malloc()或系列使用动态内存分配。动态分配的内存的生命周期保持有效,除非通过使用free()调用取消分配(或者,在程序终止之前,无论哪个更早),所以即使在函数返回之后,您也可以使用相同的内容。

答案 1 :(得分:0)

这里的问题是范围:您的array_allocator仅在自己执行的持续时间内分配数组。分配了#39;数组是array_allocator范围的本地数据,因此当它返回时,它们可能不再被使用。

要分配比呼叫者范围更长的内存,请使用malloc。但是不要忘记free它!

答案 2 :(得分:0)

abarray_allocator的局部变量。局部变量位于堆栈中,仅在函数内部可用。返回后,堆栈会被覆盖,包括ab。你看到的是那些新的“随机”堆栈值。

您需要使用malloc。但是,在完成freea后,您必须确保b记忆。

读取C中的指针和数组;网上有很多好的资料,只是在搜索一下。

答案 3 :(得分:0)

这不起作用,因为您指定的值仅存在于本地:

(*a) = (int[5]) {0, 1, 2, 3, 4};
(*b) = (int[5]) {5, 6, 7, 8, 9};

你应该这样做:

*a = malloc(sizeof(int)*5);
*b = malloc(sizeof(int)*5);
(*a)[0] = 0;
(*a)[1] = 2;
(*a)[2] = 2;
(*a)[3] = 3;
(*a)[4] = 4;
(*b)[0] = 5;
(*b)[1] = 6;
(*b)[2] = 7;
(*b)[3] = 8;
(*b)[4] = 9;

另外,请不要忘记free(a)

末尾的free(b)some_function()