Получение выровненного указателя внутри хранилища для размещения объектаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Получение выровненного указателя внутри хранилища для размещения объекта

Сообщение Anonymous »

У меня есть хранилище в виде массива байтов.
В стеке

Код: Выделить всё

// storage on the stack, no requirement on alignment
unsigned char storage[N];
Или в куче

Код: Выделить всё

// storage on the heap, no requirement on alignment
unsigned char *storage = new unsigned char[N*sizeof(T)];
В духе monotonic_resource_buffer
В какой-то момент у меня есть действительный указатель p на некоторый байт хранилища, и я хотел бы найти следующий соответствующим образом выровненный адрес для размещения объекта типа T (я предполагаю, что в духе monotonic_resource_buffer в буфере «после» не живут никакие другие объекты) p).

Код: Выделить всё

// let p a pointer to a byte inside storage, originally set to storage
// issue storage+N-p is std::ptrdiff_t not std::size_t
// remaining storage should probably be kept up to date manually into a dedicated variable

// properly aligned storage to hold M contiguous T objects or nullptr
std::align(alignas(T),M,p,storage+N-p);
// or (using a dedicated variable)
std::align(alignas(T),M,p,remaining_space);
// major issue, the required remaining_space cannot be known in advance AFAIU,
// it may lead to expansive reallocation(s) and copy(ies)
(Примечание: во фрагменте выше есть опечатка, это alignof, а не alignas, но я оставляю все как есть, чтобы не делать недействительной часть уже предоставленного ответа по поводу этой опечатки)
До недавнего времени я думал, что можно обойтись без std::align, выполнив арифметические действия над представлением значения указателя (например, после приведения в std::uintptr_t, когда он доступен), чтобы проверить или настроить выравнивание и вычислить требования к пространству. Но из стандарта:

Представление значений типов указателей определяется реализацией

Только арифметика указателей внутри массивов определяется абстрактным образом. Я не могу полагаться на целочисленную арифметику над значением, возвращаемым reinterpret_cast(p), для вычисления выровненного местоположения и требуемого размера буфера.
Но использование std::align вызывает проблему с требуемым размером хранилища.

Не существует портативного и законного способа заранее оценить потребность в пространстве для хранения разнородных данных объекты?

В конце концов я нашел еще одно обсуждение проверки выравнивания, которое вызывает аналогичные опасения по поводу использования модуля для проверки выравнивания: действительно ли четко определено, как проверять выравнивание указателя с использованием целочисленного значения указателя?

Подробнее здесь: https://stackoverflow.com/questions/787 ... ace-object
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»