在C中的其他函数中分配数组的函数
Function for allocating arrays in other function in C
我在使用一个函数在另一个函数中分配数组时遇到问题。这是导致问题的部分:
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_function()
.
处打印数组值之前添加一些 printf()
函数,甚至会发生变化
这里的问题是范围:您的 array_allocator
仅在其自身执行期间分配数组。 'allocated' 数组在 array_allocator
的范围内是局部的,所以当它 returns 时它们可能不再被使用。
a
和b
是array_allocator
的局部变量。局部变量在堆栈上,只有在函数内部时才可用。在您 return 之后,堆栈将被覆盖,包括您的 a
和 b
。您看到的是那些新的 'random' 堆栈值。
您需要使用 malloc
。但是你必须确保在完成 a
和 b
.
之后你正在 free
记忆
阅读 C 中的指针和数组;网上有很多不错的 material,只需搜索一下 duckduckgo。
这不起作用,因为您分配的值仅存在于本地:
(*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,(强调我的)
[...] If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
所以,一旦你的函数 returns,复合文字就不再存在了。因此,在 some_function()
中取消引用 a
又是 UB。
解决方案:您可能希望通过 malloc()
或 family 使用动态内存分配。动态分配内存的生命周期保持有效,除非使用 free()
调用解除分配(或者,为了挑剔,直到程序终止,以较早者为准),因此即使在函数 returns 之后,您也可以使用一样的。
我在使用一个函数在另一个函数中分配数组时遇到问题。这是导致问题的部分:
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_function()
.
printf()
函数,甚至会发生变化
这里的问题是范围:您的 array_allocator
仅在其自身执行期间分配数组。 'allocated' 数组在 array_allocator
的范围内是局部的,所以当它 returns 时它们可能不再被使用。
a
和b
是array_allocator
的局部变量。局部变量在堆栈上,只有在函数内部时才可用。在您 return 之后,堆栈将被覆盖,包括您的 a
和 b
。您看到的是那些新的 'random' 堆栈值。
您需要使用 malloc
。但是你必须确保在完成 a
和 b
.
free
记忆
阅读 C 中的指针和数组;网上有很多不错的 material,只需搜索一下 duckduckgo。
这不起作用,因为您分配的值仅存在于本地:
(*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,(强调我的)
[...] If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
所以,一旦你的函数 returns,复合文字就不再存在了。因此,在 some_function()
中取消引用 a
又是 UB。
解决方案:您可能希望通过 malloc()
或 family 使用动态内存分配。动态分配内存的生命周期保持有效,除非使用 free()
调用解除分配(或者,为了挑剔,直到程序终止,以较早者为准),因此即使在函数 returns 之后,您也可以使用一样的。