Can I use std :: vector as a facade for a pre-allocated (raw) array?

I purchased a memory cell from DirectX, where my vertex information is stored. An extremely convenient way to process vertex information is to use the std :: vector <> structure containing the vertex information.

Given that I have a pointer to a large buffer, can I use std :: vector to control the elements in the buffer? Building std :: vector regularly makes it have its own address, which I don't want. Can I use operator placement in some way?

+8
c ++ vector facade memory-address
source share
2 answers

Yes, you can. Use a custom dispenser . At this return address of your DirectX memory allocator.

Here is a complete example based on the answer Force examples of custom C ++ STL allocators? . This solution uses a new allocation in the dispenser.

#include <memory> #include <iostream> #include <vector> using namespace std; template <typename T> class placement_memory_allocator: public std::allocator<T> { void* pre_allocated_memory; public: typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; template<typename _Tp1> struct rebind { typedef placement_memory_allocator<_Tp1> other; }; pointer allocate(size_type n, const void *hint=0) { char* p = new(pre_allocated_memory)char[n * sizeof(T)]; cout << "Alloc " << n * sizeof(T) << " bytes @" << hex << (void*)p <<endl; return (T*)p; } void deallocate(pointer p, size_type n) { cout << "Dealloc " << n << " bytes @" << hex << p << endl; //delete p; } placement_memory_allocator(void* p = 0) throw(): std::allocator<T>(), pre_allocated_memory(p) { cout << "Hello allocator!" << endl; } placement_memory_allocator(const placement_memory_allocator &a) throw(): std::allocator<T>(a) {pre_allocated_memory = a.pre_allocated_memory;} ~placement_memory_allocator() throw() { } }; class MyClass { char empty[10]; char* name; public: MyClass(char* n) : name(n){ cout << "MyClass: " << name << " @" << hex << (void*)this << endl; } MyClass(const MyClass& s){ name = s.name; cout << "=MyClass: " << s.name << " @" << hex << (void*)this << endl; } ~MyClass(){ cout << "~MyClass: " << name << " @" << hex << (void*)this << endl; } }; int main() { // create allocator object, intialized with DirectX memory ptr. placement_memory_allocator<MyClass> pl(DIRECT_X_MEMORY_PTR); //Create vector object, which use the created allocator object. vector<MyClass, placement_memory_allocator<MyClass>> v(pl); // !important! reserve all the memory of directx buffer. // try to comment this line and rerun to see the difference v.reserve( DIRECT_X_MEMORY_SIZE_IN_BYTES / sizeof(MyClass)); //some push backs. v.push_back(MyClass("first")); cout << "Done1" << endl; v.push_back(MyClass("second")); cout << "Done1" << endl; v.push_back(MyClass("third")); cout << "Done1" << endl; } 
+7
source share

The std::vector elements are dynamically allocated on the heap (from new to std::vector ) so that they are always contiguous in memory. Therefore, if your vertex structure, using std::vector<vertex> is not what you want, since the elements of the vector will not be located in your large buffer.

You can use std::vector<vertex*> , for example, for example:

 vertex* bigBuffer; // provided by DirectX size_t bigBufferLen; // provided by DirectX std::vector<vertex*> array; for (size_t i = 0; i < bigBufferLen; ++i) { array.push_back(bigBuffer + i * sizeof(vertex)); } 
0
source share

All Articles