Почему malloc() выделяет 4K минимум?
От: unz0r  
Дата: 04.02.06 02:42
Оценка:
Всем здравствовать.

С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?

Буду очень благодарен если кто подскажет.

05.02.06 10:20: Перенесено модератором из 'C/C++' — Odi$$ey
Re: Почему malloc() выделяет 4K минимум?
От: Chiрset Россия http://merlinko.com
Дата: 04.02.06 04:22
Оценка:
Здравствуйте, unz0r, Вы писали:

U>Всем здравствовать.


U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?


U>Буду очень благодарен если кто подскажет.


Советую копать в сторону Win32.
"Всё что не убивает нас, делает нас сильнее..."
Re[2]: Почему malloc() выделяет 4K минимум?
От: unz0r  
Дата: 04.02.06 05:13
Оценка:
Здравствуйте, Chiрset, Вы писали:

U>Советую копать в сторону Win32.


В смысле? Я сделал маленький тестовый проект — в нем malloc(1) ест 16 байт. Но в большом проекте — 4Kb.
Но вообще что-то непонятное происходит. Если я _переименовываю_ полученный .exe файл проекта, например на X.exe, то магическим образом malloc(1) вместо 4Kb ест 16 байт. Если хоть одной буквой имя экзешника отличается от заложенного в проекте — то все работает как надо. Еще странность — вроде бы переименованная программа пошустрее работает.

Есть идеи откуда вообще такой бред может вылезать? Проект небольшой, Win32, использует стили XP, потоки через _beginthread() (/MT), больше ничего подозрительного в нем нет.
Я вообще первый раз слышу чтобы программа работала по разному в зависимости от имени exe файла.
Re[3]: Почему malloc() выделяет 4K минимум?
От: Chiрset Россия http://merlinko.com
Дата: 04.02.06 05:45
Оценка:
Здравствуйте, unz0r, Вы писали:

U>Здравствуйте, Chiрset, Вы писали:


U>>Советую копать в сторону Win32.


U>Есть идеи откуда вообще такой бред может вылезать? Проект небольшой, Win32, использует стили XP, потоки через _beginthread() (/MT), больше ничего подозрительного в нем нет.

U>Я вообще первый раз слышу чтобы программа работала по разному в зависимости от имени exe файла.

Попробуй копать в сторону диспетчиризации памяти в Win32. Сразу слёту можно предположить что диспетчер некоим образом реагирует на твою программу в зависимости от имени файла. Или у тебя где-нибудь out-of-bounds, при них тоже странные вещи возникают.
... << RSDN@Home 1.2.0 alpha rev. 634>>
"Всё что не убивает нас, делает нас сильнее..."
Re: Почему malloc() выделяет 4K минимум?
От: Сергей Мухин Россия  
Дата: 04.02.06 06:19
Оценка:
Здравствуйте, unz0r, Вы писали:

U>Всем здравствовать.


U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?



    1. на каждый malloc(1)?
    2. как измерял?
---
С уважением,
Сергей Мухин
Re[2]: Почему malloc() выделяет 4K минимум?
От: unz0r  
Дата: 04.02.06 06:28
Оценка:
Здравствуйте, Сергей Мухин, Вы писали:
U>1. на каждый malloc(1)?
U>2. как измерял?

Измерял так:

char *s;
for(int i = 0; i < 10000; i++) s = (char *)malloc(1);


Windows Task Manager / Memory Usage, отнимал два значения (с кодом/без) и делил на 10000

В нормальной ситуации получалось ~ 16 байт, в ненормальной — 4 Kb.

Все malloc-и в программе ведут себя так, меня собственно это и насторожило.
Re[4]: Почему malloc() выделяет 4K минимум?
От: unz0r  
Дата: 04.02.06 06:40
Оценка:
Здравствуйте, Chiрset, Вы писали:

U>Попробуй копать в сторону диспетчиризации памяти в Win32. Сразу слёту можно предположить что диспетчер некоим образом реагирует на твою программу в зависимости от имени файла. Или у тебя где-нибудь out-of-bounds, при них тоже странные вещи возникают.


А вообще такое бывает, что диспетчер реагирует на имя файла?

B out-of-bounds я бы поверил, однако segfault-ов не было ни разу, да и неясно как out-of-bounds повлияет на malloc(). Я пошурудил в malloc.c, нашел там только округление в виде
#define BYTES_PER_PARA      16
size = (size + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1);

Но зачем ей аж целая страница понадобилась — непонятно.
Почему malloc() выделяет 4K минимум?
От: Eugene Kilachkoff Россия  
Дата: 04.02.06 08:15
Оценка: 23 (5) -1
#Имя: FAQ.winapi.ImageFileExecutionOptions
Здравствуйте, unz0r, Вы писали:

U>В смысле? Я сделал маленький тестовый проект — в нем malloc(1) ест 16 байт. Но в большом проекте — 4Kb.

U>Но вообще что-то непонятное происходит. Если я _переименовываю_ полученный .exe файл проекта, например на X.exe, то магическим образом malloc(1) вместо 4Kb ест 16 байт. Если хоть одной буквой имя экзешника отличается от заложенного в проекте — то все работает как надо. Еще странность — вроде бы переименованная программа пошустрее работает.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

Оно ?
Re: Почему malloc() выделяет 4K минимум?
От: _Winnie Россия C++.freerun
Дата: 04.02.06 09:03
Оценка:
Здравствуйте, unz0r, Вы писали:

U>Всем здравствовать.


U>С удивлением обнаружил что вызов malloc(1) вместо положенных 16 байт, жрет целых 4K памяти. На каком этапе проекта это произошло — не знаю, может накрутил что-то кривыми руками в настройках компилятора (VC++ .NET)?


U>Буду очень благодарен если кто подскажет.


Да, в Windows гранулярность страниц — 4 килобайта.
Выделив 1 байт, нам windows отдаёт целую страничку. Но если выделить потом ещё один байт, менеджер памяти положит скорее всего его в туже страничку.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[4]: Почему malloc() выделяет 4K минимум?
От: unz0r  
Дата: 04.02.06 17:47
Оценка:
Здравствуйте, Eugene Kilachkoff, Вы писали:

EK>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options


EK>Оно ?


Гений! Оно!
gflags оставил мусор в реестре, зараза. Вообще предупреждать надо бы о таких фокусах, MS иногда забывается.
Если бы не ты, сидеть мне за отлавливанием несуществующего бага в проекте. Спасибо!
Re[5]: Почему malloc() выделяет 4K минимум?
От: Eugene Kilachkoff Россия  
Дата: 05.02.06 12:35
Оценка:
Здравствуйте, 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. ЕМНИМС, там дело было в библиотеках, но видимо подобных твиков в виндах навалом.
Интересно было бы, конечно, разобраться что за флаг отвечает за такую аллокацию, и зачем это могло быть нужно....
Re[6]: Почему malloc() выделяет 4K минимум?
От: Alex Fedotov США  
Дата: 05.02.06 16:26
Оценка: 7 (2)
Здравствуйте, 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
-- Alex Fedotov
Re[2]: Почему malloc() выделяет 4K минимум?
От: RunderBin Россия  
Дата: 02.03.07 10:42
Оценка:
_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 байт (у меня опять же). Она то почти за всем следит Ну .... почти
Люди — ангелы презирающие условности, желающие восстановить друвнейшую связь со звездной динамомашиной в вечности мироздания
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.