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

用于在C中的其他函数中分配数组的函数,c,arrays,pointers,compound-literals,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,

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

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)

不知何故,数组分配后的值变得随机,甚至会发生变化,如果我在
some\u function()
处打印数组值之前添加一些
printf()
函数,这里的问题是范围:您的
array\u分配器只在其自身执行期间分配数组。“已分配”数组是
数组分配器
作用域的本地数组,因此当它返回时,它们可能不再被使用


要分配超出调用方作用域的内存,请使用。但别忘了也要这样做

a
b
数组分配器的局部变量。局部变量位于堆栈上,仅在函数内部可用。返回后,堆栈将被覆盖,包括
a
b
。您看到的是那些新的“随机”堆栈值

你需要使用。但是,在完成
a
b
之后,必须确保
释放了内存


阅读C语言中的指针和数组;网上有很多好的资料,只需搜索一下就可以了。

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

(*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;

另外,不要忘记在
some_function()的末尾
free(a)
free(b)
array_allocator()函数中,您使用的是复合文字

关于复合文字的用法,请引用
C11
标准,第§6.5.2.5章(重点)

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

因此,一旦函数返回,复合文字就不再存在。因此,在
some_function()
中取消对
a
的引用依次被取消


解决方案:您可能希望通过
malloc()
或family使用动态内存分配。动态分配的内存的生存期保持有效,除非通过使用
free()
调用解除分配(或者,挑剔地说,直到程序终止,以较早者为准),因此即使在函数返回后,您也可以使用相同的内存。

您实际上没有分配内存。您可能需要
malloc
。一种更高级的可能性是分割现有块(甚至可能是静态/全局内存)并将其称为“已分配”,但不能像现在这样使用堆栈内存。我建议使用
malloc
或操作系统调用来获取内存;这是因为它们具有自动存储时间。如果对象是
静态的
,那么尽管变量是局部的,代码仍然可以工作。此外,没有必要提及“堆栈”——就C而言,没有“堆栈”。这是一个公认的常见实现细节,但它与此无关,因为语言本身的抽象语义足以描述所讨论的代码不正确的原因。@ParamagneticCroissant是的,问题在于它们是局部的。但是你是对的,它们也不应该是静态的。我试图给一个务实(双关语)的解释,这似乎是一个初学者的问题。这就是为什么我也提到了堆栈,没有给出一个理论上的解释,只是让事情变得不那么清楚。感谢你的回答,我认为做(*a)=(int[5]){0,1,2,3,4}与分配内存和稍后定义输入是一样的,但显然不是。谢谢