Заставить распределитель вектора указывать на определенное местоположение - PullRequest
0 голосов
/ 21 октября 2019

У меня есть простой буфер в стиле c, выделенный с пользовательскими требованиями к выравниванию - выравнивание по размеру 64 байта и выравнивание по адресу 4096 байтов. Я хочу использовать std::vector и распределить его так, чтобы указатель данных указывал на расположение вышеупомянутого буфера?

Возможно ли это? И если это так, то каковы возможные минусы? Я не буду изменять размер вектора при жизни. Я вынужден работать с vectors и у меня нет выбора.

1 Ответ

1 голос
/ 21 октября 2019

Использование вектора для этого, вероятно, является неправильным (плохая практика) - даже если вектор может выделяться только один раз и даже если вы написали пользовательский распределитель - так как вы хотите, чтобы буфер был статическим и не должен перемещаться. Кроме того, вектор должен владеть памятью и очищать (освобождать) после себя (где, как вы утверждаете, память для элементов была предварительно выделена), поэтому вектор не выглядит подходящим для контейнера с самого начала. ,

Приведение к выровненному типу указателя и использование span

Когда / если у вас есть , выможет использовать span в качестве «массива» в основном. До этого просто используйте выровненный тип и приведите к нему.

#include <iostream>
#include <type_traits>
#include <utility>
#include <span>


struct alignas(0x1000) Mine {
  unsigned char a[64];
};


typename std::aligned_storage<sizeof(unsigned char[64]), 0x1000>::type mem_seg[10]; //<-- or your own allocated storage

int main() {

   std::cout << "size: " << sizeof(Mine) << std::endl;
   std::cout << "alignment: " << alignof(Mine) << std::endl;

   Mine* begin_ = reinterpret_cast<Mine*>(&mem_seg);
   Mine* end_ = reinterpret_cast<Mine*>(&mem_seg) + 10;

   //pre-c++20 you done, work with the pointers 'normally'

   //c++20 gives you span: (an array view of sorts)
   //that works a lot like a normal container (except it's fixed size)
   std::span<Mine> mine_view(begin_, end_);


   for(auto& e : mine_view) {
       std::cout << "address check: " << &e << std::endl;
   }

   return 0;
}

https://godbolt.org/z/H3BDof

Приведенный выше выводит следующее (пример):

size: 4096

alignment: 4096

address check: 0x604000

address check: 0x605000

address check: 0x606000

address check: 0x607000

address check: 0x608000

address check: 0x609000

address check: 0x60a000

address check: 0x60b000

address check: 0x60c000

address check: 0x60d000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...