С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?
Буду очень благодарен если кто подскажет.
05.02.06 10:20: Перенесено модератором из 'C/C++' — Odi$$ey
Здравствуйте, unz0r, Вы писали:
U>Всем здравствовать.
U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?
U>Буду очень благодарен если кто подскажет.
Здравствуйте, Chiрset, Вы писали:
U>Советую копать в сторону Win32.
В смысле? Я сделал маленький тестовый проект — в нем malloc(1) ест 16 байт. Но в большом проекте — 4Kb.
Но вообще что-то непонятное происходит. Если я _переименовываю_ полученный .exe файл проекта, например на X.exe, то магическим образом malloc(1) вместо 4Kb ест 16 байт. Если хоть одной буквой имя экзешника отличается от заложенного в проекте — то все работает как надо. Еще странность — вроде бы переименованная программа пошустрее работает.
Есть идеи откуда вообще такой бред может вылезать? Проект небольшой, Win32, использует стили XP, потоки через _beginthread() (/MT), больше ничего подозрительного в нем нет.
Я вообще первый раз слышу чтобы программа работала по разному в зависимости от имени exe файла.
Здравствуйте, unz0r, Вы писали:
U>Здравствуйте, Chiрset, Вы писали:
U>>Советую копать в сторону Win32.
U>Есть идеи откуда вообще такой бред может вылезать? Проект небольшой, Win32, использует стили XP, потоки через _beginthread() (/MT), больше ничего подозрительного в нем нет. U>Я вообще первый раз слышу чтобы программа работала по разному в зависимости от имени exe файла.
Попробуй копать в сторону диспетчиризации памяти в Win32. Сразу слёту можно предположить что диспетчер некоим образом реагирует на твою программу в зависимости от имени файла. Или у тебя где-нибудь out-of-bounds, при них тоже странные вещи возникают.
Здравствуйте, unz0r, Вы писали:
U>Всем здравствовать.
U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?
Здравствуйте, Chiрset, Вы писали:
U>Попробуй копать в сторону диспетчиризации памяти в Win32. Сразу слёту можно предположить что диспетчер некоим образом реагирует на твою программу в зависимости от имени файла. Или у тебя где-нибудь out-of-bounds, при них тоже странные вещи возникают.
А вообще такое бывает, что диспетчер реагирует на имя файла?
B out-of-bounds я бы поверил, однако segfault-ов не было ни разу, да и неясно как out-of-bounds повлияет на malloc(). Я пошурудил в malloc.c, нашел там только округление в виде
Здравствуйте, unz0r, Вы писали:
U>В смысле? Я сделал маленький тестовый проект — в нем malloc(1) ест 16 байт. Но в большом проекте — 4Kb. U>Но вообще что-то непонятное происходит. Если я _переименовываю_ полученный .exe файл проекта, например на X.exe, то магическим образом malloc(1) вместо 4Kb ест 16 байт. Если хоть одной буквой имя экзешника отличается от заложенного в проекте — то все работает как надо. Еще странность — вроде бы переименованная программа пошустрее работает.
Здравствуйте, unz0r, Вы писали:
U>Всем здравствовать.
U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?
U>Буду очень благодарен если кто подскажет.
Да, в Windows гранулярность страниц — 4 килобайта.
Выделив 1 байт, нам windows отдаёт целую страничку. Но если выделить потом ещё один байт, менеджер памяти положит скорее всего его в туже страничку.
Правильно работающая программа — просто частный случай Undefined Behavior
Гений! Оно!
gflags оставил мусор в реестре, зараза. Вообще предупреждать надо бы о таких фокусах, MS иногда забывается.
Если бы не ты, сидеть мне за отлавливанием несуществующего бага в проекте. Спасибо!
Здравствуйте, unz0r, Вы писали:
EK>>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
EK>>Оно ?
U>Гений! Оно! U>gflags оставил мусор в реестре, зараза. Вообще предупреждать надо бы о таких фокусах, MS иногда забывается. U>Если бы не ты, сидеть мне за отлавливанием несуществующего бага в проекте. Спасибо!
Мне вот вспоминается тред трех-четырехлетней давности в ru.visual.cpp с участием Pavel Dvorkin, который натыкался на подобное странное поведение qsort. ЕМНИМС, там дело было в библиотеках, но видимо подобных твиков в виндах навалом.
Интересно было бы, конечно, разобраться что за флаг отвечает за такую аллокацию, и зачем это могло быть нужно....
Здравствуйте, Eugene Kilachkoff, Вы писали:
EK>>>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options EK>>>Оно ?
U>>Гений! Оно! U>>gflags оставил мусор в реестре, зараза. Вообще предупреждать надо бы о таких фокусах, MS иногда забывается. U>>Если бы не ты, сидеть мне за отлавливанием несуществующего бага в проекте. Спасибо!
EK>Мне вот вспоминается тред трех-четырехлетней давности в ru.visual.cpp с участием Pavel Dvorkin, который натыкался на подобное странное поведение qsort. ЕМНИМС, там дело было в библиотеках, но видимо подобных твиков в виндах навалом. EK>Интересно было бы, конечно, разобраться что за флаг отвечает за такую аллокацию, и зачем это могло быть нужно....
Да pageheap был включен у человека:
Q286470 How to use Pageheap.exe in Windows XP and Windows 2000
_W>Да, в Windows гранулярность страниц — 4 килобайта. _W>Выделив 1 байт, нам windows отдаёт целую страничку. Но если выделить потом ещё один байт, менеджер памяти положит скорее всего его в туже страничку.
Более того, Windows не отслеживает обращение в соседним (невыделенным) ячейкам памяти в рамках страницы (ибо x86 не предоставляет удобного механизма для этого, и даже если это сделать, то получатся тормаза при обращении к памяти и ее перестанут называть оперативной). Напомню что основной механизм защиты памяти большинства ОС для x86 стоиться на основе исключений процессора, которые генерируются на уровне страниц (4Кб/4Мб). Именно от сюда и выплывает гранулярность самой Windows. Вот к примеру взгляните на такой код:
int * pNumber = new int;
pNumber += 100;
*pNumber = 42; // Пишем мусор
исключения не возникают. (хотя у Вас могут возникнуть, ибо я не знаю в каком месте 4 килобайтной страницы Windows положит этот int).
Если прибавить не 100 интов а скажем 5000 или 10000, то скорее всего возникнет исключение (вылезли на несуществующую страницу) и Windows попросит отправить письмо во всем известное место. НО! Когда запуск происходит под отладчиком Visual Studio — размер разрешенного окна сужается до 57 байт (у меня опять же). Она то почти за всем следит Ну .... почти
Люди — ангелы презирающие условности, желающие восстановить друвнейшую связь со звездной динамомашиной в вечности мироздания