Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Странности получения динамической памяти


Автор: georain 29.5.2008, 01:41
система linux 2.6, x86_64.

Код

    long * i = new long[x];
    cout << reinterpret_cast<size_t>(i) << endl;


если x меньше 16381 то указатель находится в пределах первого Гб, а вот если больше этого числа указатель получает значение около 1е12. smile

Откуда берутся такие указатели и можно ли как-нибудь сделать чтобы они всегда в первых 2Гб были? А то у меня есть кусок старого кода, которому такие указатели не нравятся.

Автор: Ken 29.5.2008, 21:00
По идее size_t - не float, поэтому странно что cout печатает такое значение. А если использовать int вместо size_t? По крайней мере у меня в размерах меньше и больше 16кб получилось значение 134520840 (linux26, x86_32, gcc4). Но обычно вас не должно интересовать реальное значение указателья, потому что распределением адресов занимается библиотека. Но при желании вы можете переопределить оператор new и сами выделить память.

Можете показать этот кусочек кода?

Автор: georain 29.5.2008, 21:18
Цитата(Ken @  29.5.2008,  21:00 Найти цитируемый пост)
По идее size_t - не float, поэтому странно что cout печатает такое значение. 

А он и печатает число 218476039485 smile

Цитата(Ken @  29.5.2008,  21:00 Найти цитируемый пост)
Можете показать этот кусочек кода?

Собственно кусочек кода я и привёл, больше и не надо ничего.

Тут дело как раз в том что у меня x86_64, а там теоретически указатели до 2^64 могут быть smile
А у меня код и под 64 и под 32, причём под 32 код уж такой дремучий достался, что переписывать уж больно не хочется. Там 100% 64-х битные указатели в какой-нибудь int32 преобразовывается.

Товарищи что делать? помогите! smile

Автор: UnrealMan 29.5.2008, 21:56
Попробуй вывести в cout сам указатель (без преобразования в size_t). Скорее всего, результат будет тот же.

Автор: MAKCim 29.5.2008, 22:00
Цитата(georain @  29.5.2008,  01:41 Найти цитируемый пост)
если x меньше 16381 то указатель находится в пределах первого Гб, а вот если больше этого числа указатель получает значение около 1е12.

в первом случае аллокатором используются страницы, отображенные по адресам из диапазона [адрес .bss + размер .bss, brk(0))
в случае, если этих страниц не хватает (второй случай), аллокатор использует mmap() + MAP_ANONYMOUS для аллокации и отображения новых страниц
для x86-64 mmap() поддерживает флаг MAP_32BIT, обеспечивающий отображение в рамках первых 2GB
но аллокатор его не использует (т. к это потенциально ограничивает объем физической памяти, который он может запросить у ядра)

Добавлено через 2 минуты и 2 секунды
Цитата(georain @  29.5.2008,  01:41 Найти цитируемый пост)
А то у меня есть кусок старого кода, которому такие указатели не нравятся. 

если код для Linux и только, используй mmap() + MAP_32BIT
иначе оборачивай макросами

Автор: georain 29.5.2008, 22:30
Т.е. мне нужно написать свой аллокатор с использованием mmap()...

Автор: MAKCim 29.5.2008, 22:33
Цитата(georain @  29.5.2008,  22:30 Найти цитируемый пост)
Т.е. мне нужно написать свой аллокатор с использованием mmap()... 

если критичны адреса < 2GB

можно пропатчить аллокатор из glibc (вызов mmap() заменить на brk())

Автор: georain 29.5.2008, 22:41
Цитата(MAKCim @  29.5.2008,  22:33 Найти цитируемый пост)
можно пропатчить аллокатор из glibc 

А это переносимо на машину без пропатченного glibc?

offtop.
Давно интересовал вопрос: если не использовать виртуальную память, можно ли убрать страничную организацию памяти, чтобы была прямая физическая адресация? По идее это должно убрать издержки на её использование, и например это может пригодится для единственного серверного приложения на машине, типа выделить ему всю память за исключением памяти ядра. Не бейте если что, сумасшедший я smile

Автор: MAKCim 29.5.2008, 22:49
Цитата(georain @  29.5.2008,  22:41 Найти цитируемый пост)
А это переносимо на машину без пропатченного glibc?

нет, если будет использоваться динамически загружаемые libc.so, libstdc++.so

Цитата(georain @  29.5.2008,  22:41 Найти цитируемый пост)
Давно интересовал вопрос: если не использовать виртуальную память, можно ли убрать страничную организацию памяти, чтобы была прямая физическая адресация?

для узкоспециализированных задач все можно
на то они и узкоспециализированные

Автор: georain 29.5.2008, 22:55
Цитата(MAKCim @  29.5.2008,  22:49 Найти цитируемый пост)
для узкоспециализированных задач все можно

MAKCim, как вы считаете, это даст хоть какой-то минимальный прирост при обращении к памяти? Вроде даже есть процессорная команда, сложить два числа и константу, специально для этих операций.

Автор: MAKCim 30.5.2008, 15:28
Цитата(georain @  29.5.2008,  22:55 Найти цитируемый пост)
как вы считаете, это даст хоть какой-то минимальный прирост при обращении к памяти?

даст, но навряд ли это будет ощутимо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)