0

I have a simple c-style buffer allocated with custom alignment requirements - 64 byte size alignment and 4096 bytes address alignment. I wish to use a std::vector and allocate it such that it's data pointer points to the above mentioned buffer's location?

Is it possible? And if it is, then what are possible cons? I will not be resizing the vector ever during its lifetime. I am forced to work with vectors and have no choice over it.

Sisir
  • 4,584
  • 4
  • 26
  • 37
  • Possible duplicate of [Is it possible to initialize std::vector over already allocated memory?](https://stackoverflow.com/questions/21917529/is-it-possible-to-initialize-stdvector-over-already-allocated-memory) – Daniel Langr Oct 21 '19 at 06:02
  • Hi, Thanks for pointing the link out. But, my question is if the buffer has been allocated with a certain alignment, and we pass its pointer to the vector's allocator, will the vector allocation be aligned too? –  Oct 21 '19 at 07:17
  • 1
    A vector gets a memory by calling its allocator `allocate` member function. If you return an address of your pre-allocated buffer, then, the vector will use it. The problem is that the vector may call `allocate` multiple times. You then need to make sure that the address of the buffer is returned at most once. – Daniel Langr Oct 21 '19 at 08:14
  • Why don't you just use `alignas` https://en.cppreference.com/w/cpp/language/alignas ? – darune Oct 21 '19 at 08:46
  • Daniel, so what would be the best solution for me and any pointers on how to go about implementing it ? In short my problem is that I wish my vector to always point to a pre-allocated buffer which might be allocated in any arbitrary alignment. –  Oct 21 '19 at 09:32
  • Darune , I need to have consistency between the pre-allocated buffer and the vector. I am not resizing the vector at any point. –  Oct 21 '19 at 09:33
  • @abhiverma im confused, do you only have a memory segment - or do you actually have an 'allocator function' (as you wrote in the start) ? – darune Oct 21 '19 at 09:55
  • darune I have a pre-allocated buffer which is allocate to certain alignment requirement and I wish to allocate another vector such that it points to the pre-allocated buffer's location. –  Oct 21 '19 at 10:24

1 Answers1

1

Using a vector for this is probably wrong (bad practice) - even though vector might only allocate once and even if you wrote the custom allocator - since you want the buffer to be static and shouldn't be moved. Additionally the vector is supposed to own the memory and clean up(release) after itself (where as you state that the memory for the elements have been pre-allocated), so vector does not seem like a good fit for a container to begin with.

Cast to aligned pointer type and use a span

When/if you have have you could use a span as your "array view" basicly. Until that, just use an aligned type and cast to that.

#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

The above prints the following (example):

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
darune
  • 10,480
  • 2
  • 24
  • 62