函数内部的数组声明

时间:2015-05-18 12:02:57

标签: c arrays variable-length-array

编写如下代码是否安全?

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

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

 /*
 Other stuff...
 */

}

或者我偶然发现某种错误?

4 个答案:

答案 0 :(得分:2)

只要来电者确保v至少有size个元素,这是安全的,否则当然会导致问题,你不必担心,因为你无论如何都无能为力。

你还必须注意不要返回array_local,因为它会在函数返回时被释放,因为它是在函数堆栈框架中分配的。

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

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

答案 1 :(得分:2)

是的,这在C99之上和之上完全没问题。它被称为VLA

为了更加安全,您应该在使用size作为数组元素数量之前检查size的值。由于您已将int定义为-5,因此您应禁止将size的值传递给v[i]

那就是说,代码的剩余部分(作为一般建议)

  1. return不应导致内存溢出。
  2. 该数组是函数的本地数组。您永远不应该尝试返回数组的地址(通过指针或通过BindingSource bSource = new BindingSource(); bSource.DataSource = new List<int> { 1, 2, 3 }; combo.DataSource = bSource; 语句)。

答案 2 :(得分:1)

这称为Variable Length Array,它们仅存在于C99中。因此,只要您的编译器支持-c99编译标志,并且您正在使用它,代码就是有效的。

至于你是否应使用它,这取决于你期望size的大小。使用堆栈分配,您无法防止分配太多内存。如果您使用动态分配器(例如malloc),则可以检查NULL返回值,而使用VLA时,如果您要求太多,则只会查看堆栈。如果size很小,则没有任何问题。

答案 3 :(得分:1)

您可以使用动态内存分配以其他方式实现相同的功能,并且可以安全实施:

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...
 */

}