![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
En_t_end |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Товарищи... обьясните пожалуйста такую ситуацию(тривиально донельзя)
Код1
Код2
Код3
Очень позабавило то, что в Код1 можно выделить 201 байт, но юзать 1201 байт ![]() ![]() Код2 аналогичен первому... но только подтверждает тот факт, что отлов исключений бессмыслен - всё и так нормально ![]() А вот то что твориться в Код3 - это просто для меня невообразимо. Мало того, что выделяем в стеке 201 байт, юзаем 1201(именно так... хотя и системный отладчик выявляет buffer overrun - buf полностью(1200 w ровно) выводится в cout), НО И это по сути исключение не ловиться программно ![]() Товарищи, я понимаю, что вопрос на пять копеек, что 1000 лишних байт можно поюзать без проблем(интересно в каком контексте они берутся ???), и что поюзать к примеру 10000 лишних байт уже не удастся(по крайней мере в моем примере мне не удалось), но всё же... что-то тут не так ![]() |
||||||
|
|||||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 4 Всего: 67 |
что бы исключение произошло нужно сначало его выбросить....
читаем MSDN по strcpy() Each of these functions returns the destination string.No return value is reserved to indicate an error. там же: These functions are deprecated because more secure versions are available; see strcpy_s, wcscpy_s, _mbscpy_s. потому как strcpy видимо не следит за длиной строки....потому профилактикой переполнения при использовании таких функций приходится заниматься вручную.... если посмотреть предложенные в MSDN секурные функции то увидим:
-------------------- СУВ, Partizan. |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
просто повезло, могло вылетить и раньше и позже, смотря в область каких данных ты писал -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Partizan
/*ИМХО Дело не в этом... я понимаю, что strcat и strcpy - небезопасные функции. Меня интересует, почему !система! не определелила переполнение и разрешила писать в чужую область памяти. У меня вообще-то nt-система, в ней строго определены контексты процессов, нельзя взять память из чужой кучи или стека, по крайней мере вот таким образом. Получается, что Майкрософт заюзала в своей системе исключения,защищаемые ограниченные контексты процессов, но грамотно использовать их как всегда не смогла. То есть, пока системе не сообщат другие менеджеры памяти, что что-то не так с их контекстом она будет продолжать разрешать писать, пока не выброситься исключение - продолжаем писать, пока что-то... Пока рак на горе не свистнет... Почему мне нельзя выйти за границы массива операциями над указателями, а системе с её функциями можно ?, в итоге, я запускай порядка 10000 таких приложений(в цикле) получаю 10000000 байт ~10 мегабайт+-2мега самих приложений, а теперь порадуемся за ядро ![]() */ Далее, меня интересует, почему такие массивы грамотно выводятся вплодь до null-terminator ? Интересно, как же работают функции для поиска конца строки(а как ещё можно вывести "строку" ? ![]() ![]() ![]() ![]() ![]() |
|||
|
||||
chipset |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Превед!
Это не чужая область, насколько я помню, для стека резервируеться какой-то обьем памяти.
Это проблемы стандарта Си а не системы, имхо. При UB вообще есть вероятность того что ты отформатируешь C: ![]() Именно так. Где-то внутри strlen приблизительно такой код:
В Паскале, к примеру, длина строки обозначаеться в самом первом байте и это рождает то самое ограничение в 255 байт ;) Добавлено @ 07:55 Вот линк ффтему: http://www.joelonsoftware.com/articles/fog0000000319.html --------------------
|
||||||
|
|||||||
En_t_end |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
chipset,
Всё равно... ну не запишу я в чужую область памяти, но всё равно такой подход, даже не знаю, с чьей стороны(программиста или системы) губителен для процесса. Ладно это стек, согласен, здесь скорее всего это не прокатит. Но как дело обстоит с кучей ?
Я париться и не буду, я ведь тему создал, не для того, чтобы конкретную проблему решить ![]() ![]() За сЦылку спасибо! Кстати... мы никак не сможем таким методом вылезти за sizeof(a) ![]() ![]() Добавлено @ 09:09 Или всё таки char[] - в памяти - это связанный список ? ![]() ![]() |
||||
|
|||||
chipset |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Как ты себе это представляешь? Указатель в конце каждого символа?
Зависит от параметров кучи. --------------------
|
||||
|
|||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
||||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
En_t_end,
система следит за "большими" кусками памяти, выделенными VirtualAlloc. С ее точки зрения - весь Heap и весь стек - это куски памяти, принадлежащие твоему процессу. А что там внутри - это CRT-код ведает... CRT - это наследие C, который никогда в жизни ничего не проверяет (чтобы побыстрее, значит). И слава богу. Слишком жирно будет за каждым байтом следить... ![]() Кстати, память с исполняемым кодом тоже где-то рядом... Туда запросто можно влезть, если вот так с буферами лихо работать... Еще как можем... ты же сам его затираешь, когда свои "W" туда пишешь... sizeof(a) известен в единственном месте - в твоей функции main. -------------------- ... |
|||
|
||||
En_t_end |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Earnest,
...как страшно жить ![]()
То есть по сути, получается так... система резервирует какой-то кусок heap моему процессу. Далее её не волнует, что и как там твориться, единтственный хранитель драгоценной информации(кол-во байт на каждую переменную-обьект) - само же приложение. Поэтому записав за выделенную естественным путем память для конкретного массива мы просто напросто затираем нашу драгоценную информацию(в нашем же процессе), системе становиться пофигу и она выводит всю галиматью, что я успел скопировать, даже сверх нормы. В итоге процесс аварийно завершается, и система, которой на него по сути наплевать просто напросто отчищает именно тот выделенный участок heap. Вывод: никогда не юзать несекурные функции(хотя с другой стороны, можно сэкономить пару тактов, если точно знать, что в массиве поместиться то, что туда ложиться). Вывод2: увы при работе с памятью в контексте одного процесса можно вылезти без предупреждения за выделенную память, по крайней мере на несколько байт, однако результат будет весьма не забавен. |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Именно ![]() Могу еще добавить, что если программа именно вывалится, да еще сразу за порчей памяти - считай, что тебе крупно повезло. Может быть запорчен кусок данных, которые просто используются в расчетах, и гадай себе, почему при сложении 2+2 получается то 5, то 8. А как только ставишь точку прерывания - чудо - все как в аптеке = 4! Переходить через дорогу тоже страшно, если хорошо подумать. А уж садится за руль - боже упаси! Столько вокруг уродов, пеших и конных... Спасают рефлексы. В программировании то же самое. Вывод: накачивай рефлексы. -------------------- ... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |