函数内的数组声明

Array declaration inside a function

像下面这样写代码安全吗?

void func(int v[], int size) {
 int array_local[size];

 for(int i = 0; i < size; i++) array_local[i] = v[i];

 /*
 Other stuff...
 */

}

或者我会不会遇到某种错误?

只要调用者保证v至少有size个元素就是安全的,否则当然会出问题,这个你不用担心,因为你无论如何也无能为力。

你还要注意不要return array_local,因为它会在函数returns时被释放,因为它是在函数堆栈帧中分配的。

另外,上面的代码不需要复制数组,你可以直接

memcpy(array_local, v, size * sizeof(int));

是的,这在 C99 及更高版本上都非常好并且有效。它被称为VLA

为了安全起见,您应该先检查 size 的值,然后再将其用作数组的元素数。当您将 size 定义为 int 时,您应该禁止将值 -5 传递给 size.

也就是说,对于代码的其余部分(作为一般建议)

  1. v[i] 不应导致内存溢出。
  2. 数组是函数的局部数组。您永远不应该尝试返回数组的 地址(通过指针或通过 return 语句)。

这叫做Variable Length Array,它们只存在于C99中。所以只要你的编译器支持-c99编译标志,并且你正在使用它,代码就是有效的。

至于你是否应该使用它,那取决于你希望size有多大。使用堆栈分配,您无法防止分配过多内存。如果你要使用动态分配器,比如 malloc,你可以检查 NULL return 值,而使用 VLA,如果你要求太多。如果size会小一点,没问题。

您可以使用动态内存分配以其他方式实现相同的事情并且可以安全地实现:

void func(int v[], int size) {
 int *array_local = (int*)malloc(sizeof(int) * size);

 for(int i = 0; i < size; i++) *(array_local + i) = *(v + i);

 /*
 Other stuff...
 */

}