Таким образом, хотя в стандарте не говорится о стеках, большинство современных реализаций будут помещать автоматические переменные в стек, и стек обычно будет между 1M
и 8M
, который вы переполняете с размером вашего массива. Вы можете найти типичные размеры стека для разных систем здесь:
SunOS/Solaris 8172K bytes
Linux 8172K bytes
Windows 1024K bytes
cygwin 2048K bytes
Причина, по которой первый не выдает ошибку seg, заключается в том, что компилятору фактически не нужно ссылаться на какую-либо память, но если вам нужно вызвать какой-либо побочный эффект, компилятор генерирует доступ к памяти, который фактически вызовет переполнение стека. Поскольку вы сказали, что используете gcc
, если я запускаю этот код без каких-либо побочных эффектов (живой пример) он действительно изменит указатель стека, но никогда его не использует:
subq $23952048, %rsp
но если мы добавим побочный эффект через std::cin
и std::cout
(живой пример эм>):
std::cin >> tabs[maxsize-1][5] ;
std::cout << tabs[maxsize-1][5] << std::endl ;
тогда потребуется использование указателя стека:
leaq 3(%rsp), %rbx
что обычно приводит к ошибке сегмента в Unix-подобных системах.
Обратите внимание, вы также можете заметить это предупреждение:
warning: ISO C++ forbids variable length array ‘tabs’ [-Wvla]
Это связано с тем, что массивы переменной длины не являются стандартом C++ (но действительны в C99) являются расширением gcc и при использовании -pedantic
он будет предупреждать, когда вы используете расширения.
person
Shafik Yaghmour
schedule
07.11.2013
gcc
иclang
и, возможно, другие, хотя и не VS, поддерживают VLA как расширение - person Shafik Yaghmour   schedule 08.11.2013func
? Я должен фактически создать побочный эффект, чтобы вызвать ошибку seg. - person Shafik Yaghmour   schedule 08.11.2013