4

如果我这样做

int wsIdx[长度];

我有一个段错误

但如果我这样做

int *wsIdx;
wsIdx = (int *)malloc(sizeof(int) * length );

这里没有问题。

这个问题只有在我的测试中长度很高时才会出现,2560000。我有足够的内存。你能解释一下两种分配方法之间的区别,为什么第一种不起作用?谢谢你。

4

3 回答 3

5

第一个分配在“堆栈”(通常用于局部变量的区域)上,而第二个分配在“堆”上,分配给动态分配的内存区域。

您没有足够的堆栈空间以第一种方式分配,您的堆很大。

这个 SO 讨论可能会有所帮助:堆栈和堆是什么以及在哪里?.

当您动态分配内存时,您始终可以通过检查 malloc/calloc/etc 的返回值来检查分配是否成功。不幸的是,在堆栈上分配内存时不存在这种机制。

旁白:您可能会喜欢在这个问题的背景下阅读这篇文章,尤其是这部分:)

于 2012-07-21T12:20:17.103 回答
3

假设length不是一个常数,那么第一种形式是变长数组(VLA),而您刚刚遇到了它们最大的问题之一。

最佳实践是避免使用 VLA 用于“大型”数组,malloc而是使用 VLA,原因有两个:

  1. 除了崩溃或导致其他一些未定义的行为之外,他们没有报告分配失败的机制。

  2. VLA 通常分配在堆栈上,堆栈的大小通常相对有限。所以它分配失败的机会要高得多!

于 2012-07-21T12:20:35.260 回答
1

暗示auto被认为是有害的

同意已经给出的答案,如果错误代码是使用显式存储类编写的,那么这个常见问题可能会更明显。

void
not_enough_stack(void)
{
    auto int on_stack[2560 * 1000];
    printf("sizeof(stack) %d\n", sizeof(on_stack));
}
于 2012-07-21T12:42:16.047 回答