| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Ошибка при выполнении: "Stack ... was corrupted" |
| Автор: KasMP 10.12.2008, 17:59 | ||
| Тем временем, у меня появилась еще одна простенькая программка, которая компилируется без одной ошибки, без единого предупреждения и отлично выполняется при запуске из DevC++. Но в MS Visual C++ 2008 в самом конце выполнения возникает такая ошибка: ![]() Я совсем не понимаю, что может быть причиной ошибок такого рода в моем случае - у меня все переменные ограничены, все массивы ограничены, длины строк взяты с большим запасом, не в свои ячейки памяти я не лезу, т.п. и т.д.. Взгляните, пожалуйста (здесь совсем немного и несложно - перевод числа из арабской СС в римскую):
|
| Автор: bsa 10.12.2008, 18:31 |
| %d требует указатель на int, а у тебя number типа short |
| Автор: KasMP 10.12.2008, 18:37 |
Действительно, стоило изменить тип переменной number и тип формального параметра number, как все прошло Не думала, что эта разница столь принципиальна |
| Автор: bsa 11.12.2008, 12:40 | ||
|
| Автор: KasMP 11.12.2008, 19:23 | ||
| bsa, благодарю Теперь буду знать еще один спецификатор Пыталась понять, почему это так существенно По сути
Т.е. конкретно в моем случае получается "представить переменную типа short int как int". В чем проблема? Множество значений вкладывается, недостающие до int биты можно заполнить нулями-единицами в зависимости от знака. Вот если "представить переменную типа int как short int", то я бы тоже стала сопротивляться... А переход от большего к меньшему должен быть возможен, имхо (DevC++ со мной согласен |
| Автор: mes 11.12.2008, 20:59 |
ты запихнула в стек переменную размером в два байта (short int), а scanf запишет туда 4 байта(%d), в результате перезапишет чужие данные которые были в стеке. Имхо DevCpp просто не проверяет стек на возможное повреждение, а Студийный компилятор вероятно на границах стека ставит свою сигнатуру и после операций со стеком проверяет ее - если затерта , значит стек разрушен... |
| Автор: bsa 11.12.2008, 22:20 |
| KasMP, вообще-то смысл этих спецификаторов в том, что ими ты определяешь не только способ отображения, но еще и типы данных, с которыми должна работать функция. Ни компилятор, ни она сама не могут иначе определить их самостоятельно (почитай про функции с переменным числом аргументов и стандартный заголовочный файл stdarg.h). Например, чтобы избежать переполнения (выхода за границы) буфера при чтении строки с помощью scanf, нужно в спецификаторе указывать размер этого буфера: %20s - буфер на 20 символов. Таким образом, scanf считает в него только первые 20 букв. Дальше, есть такая штука, как "выравнивание". Т.е. в стеке нельзя просто выделить память, не кратную какому-то числу (обычно, 4 байта). short int - это два байта. Т.е. чтобы разместить эту переменную в стеке, нужно выделить 4 байта. Компилятор gcc (который входит в состав Dev-Cpp), видимо, делает выравнивание без генерации какого-либо дополнительного кода проверки выхода за границы переменной, а Visual C++ делает. |
| Автор: mes 11.12.2008, 23:42 |
мне кажется что выравнивание на стек не распространяется.. хотя точно не знаю..и даже не знаю где посмотреть ) |
| Автор: bsa 21.12.2008, 23:52 |
| KasMP, в настройках компиляции DevCpp поставь -Wall и тебе он будет писать предупреждение при ошибке в спецификаторе. А надежность тут непричем. |