У меня есть следующий очень простой код, который отлично работает:
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;
}
У тебя есть идеи почему? Буду очень признателен за помощь, спасибо ^^
Поэтому, хотя в стандарте не говорится о стеках, большинство современных реализаций автоматические переменные в стеке, и стек будет обычно между 1M
а также 8M
который вы переполните с вашим размером массива. Вы можете найти типичные размеры стеков для разных систем Вот:
SunOS/Solaris 8172K bytes
Linux 8172K bytes
Windows 1024K bytes
cygwin 2048K bytes
Причина, по которой первый не вызывает ошибки, заключается в том, что компилятору на самом деле не нужно ссылаться на какую-либо память, но если вам нужно вызвать какой-либо побочный эффект, то компилятор генерирует доступ к памяти, что приведет к переполнению стека. Так как вы сказали, что используете 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
он будет предупреждать, когда вы используете расширения.
Других решений пока нет …