成功分配数组太大时访问指针时出错

时间:2013-11-07 20:49:03

标签: c++ arrays pointers fault

我有以下非常简单的代码,完美无缺:

void func(int *tab)
{
    return;
}

int main()
{
    int maxsize = 999*999;
    int tabs[maxsize][6];

    return 0;
}

然而,当我修改主要部分以便我获得它时,它会崩溃。

int main()
{
    int maxsize = 999*999;
    int tabs[maxsize][6];

    func(tabs[0]);

    return 0;
}

你知道为什么吗?我非常感谢你对此的帮助,谢谢^^

1 个答案:

答案 0 :(得分:2)

因此,尽管标准没有讨论堆栈,但大多数现代实现都会将自动变量放在堆栈上,而堆栈通常会在1M8M之间溢出与您的数组大小。您可以找到不同系统here的典型堆栈大小:

SunOS/Solaris   8172K bytes
Linux           8172K bytes
Windows         1024K bytes
cygwin          2048K bytes

第一个没有seg错误的原因是因为编译器实际上不必引用任何内存但是如果你需要引起一些副作用,那么编译器会生成一个内存访问,这将导致实际的堆栈溢出。既然你说使用gcc如果我运行这个代码而没有任何副作用( live example ),它确实会调整堆栈指针但从不使用它:

subq    $23952048, %rsp

但如果我们通过std::cinstd::cout live example )添加副作用:

std::cin >> tabs[maxsize-1][5] ;
std::cout << tabs[maxsize-1][5] << std::endl ;

然后它将需要使用堆栈指针:

leaq    3(%rsp), %rbx

通常会在类Unix系统上生成 seg fault

注意,您可能还会注意到此警告:

warning: ISO C++ forbids variable length array ‘tabs’ [-Wvla]

这是因为variable length arrays不是标准 C ++ (但在 C99 中有效)是gcc extension并且在使用{{1}时当你使用扩展时它会发出警告。