简体   繁体   中英

One class with a vector data member

I would like to define a class with a vector data member. The class looks as follows

class A{
...
private:
     std::vector<int> v1;
...
};

If I use operator new to allocate memory for class A, the program is OK. However, if I get the memory from the pre-allocated memory and cast the pointer to type A*, the program will crash.

A* a = new A;
A* b = (A*)pre_allocated_memory_pointer.

I need one vector with variable size and hope to get the memory for A from one pre-allocated memory. Do you have any idea about the problem?

An std::vector is an object that requires initialization, you cannot just allocate memory and pretend you've got a vector .

If you need to control where to get the memory from the solution is defining operator::new for your class.

struct MyClass {
    std::vector<int> x;
    ... other stuff ...

    void *operator new(size_t sz) {
        ... get somewhere sz bytes and return a pointer to them ...
    }

    void operator delete(void *p) {
        ... the memory is now free ...
    }
};

Another option is instead to specify where to allocate the object using placement new:

struct MyClass {
    std::vector<int> x;
    ... other stuff ...
};

void foo() {
    void * p = ... get enough memory for sizeof(MyClass) ...

    MyClass *mcp = new (p) MyClass();

    ... later ...

    mcp->~MyClass(); // Call destructor

    ... the memory now can be reused ...
}

Note however that std::vector manages itself the memory for the contained elements and therefore you'll need to use stl "allocators" if you want to control where the memory it needs is coming from.

It is not enough to cast the pre-allocated memory poiner to your user-defined type unless this UDT is "trivial".

Instead, you may want to use the placement new expression to actually call the constructor of your type at the provided region of memory:

A* b = new(pre_allocated_memory_pointer) A();

Of course, you need to ensure that your memory is properly aligned and can fit the whole object (ie its size is >= sizeof(A) ) beforehand.

Don't also forget to explicitly call the destructor for this object before de-allocating the underlying memory.

b.~A();
deallocate(pre_allocated_memory_pointer);

As I understand your question you are confusing the data memory of the std::vector with the memory it takes up as a member.

If you convert pre_allocated_memory_pointer to A* , then no constructor got called and you have an invalid object there. This means that the v1 member will not have been constructed and hence no memory has been allocated for the vector.

You could use placement new to construct the A instance at the pre_allocated_memory_pointer position but I doubt that is what you want.

In my opinion you want a custom allocator for the vector that gets the memory for the vector's data from the preallocated memory pool.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM