我在 SO 上找到了一个答案,建议使用以下解决方案来重新初始化 c 中的数组。
int *foo = (int[]){1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)
我不确定这样的语法到底会做什么,我有几个问题:
如果我的数组是之前创建的,它会导致内存泄漏吗?
double *my_array = (double[]){1.1, 2.2, 3.3, 4.4, 5.5};
...
my_array = (double[]){-1.1, -2.2, -3.3}; // Do i need to call free(my_array) first?
Run Code Online (Sandbox Code Playgroud)
是否允许在函数调用中使用这种方法?
void foo(int *arr)
{
arr = (int[]){-2, -7, 1, 255};
}
int main()
{
int *my_array = (int[]){1, 2, 3};
foo(my_array);
if (my_array[2] != 1)
return -1;
}
Run Code Online (Sandbox Code Playgroud)
概括:
首先,声明int *foo创建foo了一个指针,而不是一个数组。
(int[]){1,2,3,4,5}是复合字面量。很少有充分的理由以这种方式设置指向复合文字的指针。
复合文字是自动管理的,因此您无需释放它们。如果复合字面量出现在任何函数之外,则它具有静态存储持续时间;它存在于程序的整个执行过程中。否则,它具有与它所在的块相关联的自动存储持续时间,并且当该块的执行结束时,它的内存保留将结束。如果在块执行结束后使用指针,则不应设置指向此类复合文字的指针。
在这段代码中:
void foo(int *arr)
{
arr = (int[]){-2, -7, 1, 255};
}
Run Code Online (Sandbox Code Playgroud)
arr设置为指向复合文字,但arr只是一个函数参数。当函数返回时,它实际上不复存在。
在这段代码中:
int *my_array = (int[]){1, 2, 3};
foo(my_array);
if (my_array[2] != 1)
return -1;
Run Code Online (Sandbox Code Playgroud)
当foo被调用时,它的参数arr设置为值my_array。当arr被内改变foo,它不会影响my_array。my_array仍将指向(int[]){1, 2, 3}. 这将是正确的,无论是否arr设置为指向复合文字、分配的内存或其他任何内容,:更改函数内的参数不会更改作为参数传递的内容。
要从函数中获取指针,您可以返回它,也可以传递一个指向指针的指针,以便函数具有指针的地址:
void foo(int **arr)
{
*arr = (int []) { -2, -7, 1, 255 };
}
int main(void)
{
int *my_array = (int []) { 1, 2, 3 };
foo(&my_array);
…
}
Run Code Online (Sandbox Code Playgroud)
但是, thenfoo会将其复合文字的地址放入函数结束后使用的指针中。在这种情况下,您应该调用malloc保留内存,然后将数据复制到分配的内存中。稍后,在程序处理完这些数据后,它会调用free释放内存。