Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Размещение объекта в памяти 
V
    Опции темы
ForceKeeper
Дата 16.1.2011, 02:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 17.3.2010
Где: Минск

Репутация: нет
Всего: нет



Есть класс, в который я не могу залезть ручками, и мне нужно располагать объекты данного класса по адресам, которые определю я сам. Можно ли еще это как-то сделать без глобальной перегрузки new?
PM MAIL WWW   Вверх
azesmcar
Дата 16.1.2011, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Да.
Код

new (ptr) X();

http://en.wikipedia.org/wiki/Placement_syntax
PM   Вверх
ForceKeeper
Дата 16.1.2011, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 17.3.2010
Где: Минск

Репутация: нет
Всего: нет



Ага, тогда тут по теме еще такой вопрос появился:

Вообще я попробую написать собственный аллокатор и соответственно мне нужно проводить выравнивание. В туторе, который я смотрел, там адреса сразу были записаны в 32-битные ансайты и соответственно оперировали с ними (в частности использовали побитовое *и* для выделения окончания адреса). Так вот я хотел свои void* при помощи intptr_t reinterpret_cast перекинуть в инты, осуществить выравнивание и затем обратно кинуть исправленный адрес в указатель. Но потом мне сказали, что на 64-битных форточках адрес может быть восьмибайтовым, в то время как инт четырехбайтовый. Это так? Если да, то как бороться с этой проблемой?
PM MAIL WWW   Вверх
azesmcar
Дата 17.1.2011, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Код

template <typename T>
T* align(T* ptr, std::size_t align)
{
    T* nptr = static_cast<T*>(0);
    return nptr + (((ptr - nptr) + align - 1) & ~(align - 1));
}

Вот так должно быть переносимо. По сути ptrdiff_t обязан быть достаточного размера, чтобы хранить разницу двух указателей, нигде не говорится, что второй указатель не может быть null, т.е. ptrdiff_t (результат вычитания двух указателей) должен быть минимум того же размера, что и сам указатель. Я так думаю © smile 

Это сообщение отредактировал(а) azesmcar - 17.1.2011, 09:33
PM   Вверх
xvr
Дата 17.1.2011, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  17.1.2011,  09:27 Найти цитируемый пост)
Вот так должно быть переносимо
Переносимо, но неправильно  smile Разница между указателями на T (T*) будет выражена в sizeof(T), а не в байтах  smile Так что надо приводить указатель к целочисленному типу, и с ним уже играться. И приводить надо к size_t


PM MAIL   Вверх
azesmcar
Дата 17.1.2011, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  17.1.2011,  15:13 Найти цитируемый пост)
Переносимо, но неправильно   Разница между указателями на T (T*) будет выражена в sizeof(T),

а, ну да smile сперва написал на char, потом заменил на T*..
Код

void* align(void* ptr, std::size_t align)
{
    char* nptr = static_cast<char*>(0);
    return nptr + (((static_cast<char*>(ptr) - nptr) + align - 1) & ~(align - 1));
}

пусть будет вот так

Это сообщение отредактировал(а) azesmcar - 17.1.2011, 15:19
PM   Вверх
ForceKeeper
Дата 17.1.2011, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 17.3.2010
Где: Минск

Репутация: нет
Всего: нет



Эм, только что проверил для адреса 0x50341233 с 16-байтовым выравниванием, результат был 0x50341240. То есть как и положено. Для 8-байтового пойнтера 0x0000000050341233 аналогично 0x0000000050341240
PM MAIL WWW   Вверх
azesmcar
Дата 17.1.2011, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  17.1.2011,  15:13 Найти цитируемый пост)
И приводить надо к size_t

а есть ли гарантия, что size_t того же размера, что и void*?

PM   Вверх
xvr
Дата 17.1.2011, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @ 17.1.2011,  15:24)
Цитата(xvr @  17.1.2011,  15:13 Найти цитируемый пост)
И приводить надо к size_t

а есть ли гарантия, что size_t того же размера, что и void*?

Практически - да. Т.к. size_t описывает тип, в который должен влезть размер любого объекта в памяти, т.е. размерностью не менее размерности адресного пространства. (Однако никто не может запретить поинтеру быть больше, чем размерность адресного пространства - например не использовать часть битов представления поинтеров).
Надо бы в стандарте глянуть  smile 
PM MAIL   Вверх
azesmcar
Дата 17.1.2011, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  17.1.2011,  15:57 Найти цитируемый пост)
Надо бы в стандарте глянуть    

я вроде как не нашел, потому через ptrdiff_t сделал.
может плохо искал, если что найдешь дай знать.
PM   Вверх
baldina
Дата 17.1.2011, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



строго говоря для безопасного и переносимого хранения указателей следует использовать uintptr_t
хотя в большинстве практических случаев sizeof(size_t)==sizeof(uintptr_t)
PM MAIL   Вверх
azesmcar
Дата 18.1.2011, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(baldina @  17.1.2011,  17:54 Найти цитируемый пост)
строго говоря для безопасного и переносимого хранения указателей следует использовать uintptr_t

но это в новом стандарте, а пока...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1647 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.