Location - new address and raw memory address

The result of allocating a new one always seems to be the same as the memory pointer I provide to the new allocation. With GCC, this seems to be true even for classes with virtual functions, like ...

#include <iostream>
#include <vector>

using namespace std;

class A
{
public:
    int a;
    virtual ~A() {}
};

int main()
{
    void *mem = malloc(sizeof(A));
    A* ptr = new(mem) A();

    cout << "sizeof(T) = " << sizeof(A) << endl;
    cout << "mem = " << mem << endl;
    cout << "ptr = " << ptr << endl;
    cout << "addr a = " << &(ptr->a) << endl;

    ptr->~A();
    free(mem);

    return 0;
}

      

The output of this program (note: 64-bit Linux) ...

sizeof(T) = 16
mem = 0x1a41010
ptr = 0x1a41010
addr a = 0x1a41018

      

Does C ++ guarantee that mem and ptr are identical, or is this just a GCC coincidence? In a larger portable program, will I need to store both mem and ptr, or can I just store one and execute as needed?

To clarify the question a bit, I know that memory allocators sometimes put the size of the allocated block in a word up to that specified in the block of memory. Can C ++ compilers use similar tricks and tell the VMT pointer in the word to be before the block of memory pointed to by the object pointer? In this case mem and ptr will be different.

+3


source to share


2 answers


Yes, they are the same. You might want to remember the memory address as a pointer to void and the object address as a typed pointer, but you can use. In a sense new

, it is a way to "convert" a memory address into an object (by creating it). Here is the complete picture (note there are no casts):

void * addr = std::malloc(sizeof(T));  // or ::operator new(sizeof(T))
T * p = ::new (addr) T;                // "new" gives you an object pointer
p->~T();
std::free(addr);

      



This is only true for the version without new

. Array-placement-new is different, but substantially unusable .

You might like your implementation std::allocator

to see the placement and the new action in action.

+4


source


You are using void* operator new (std::size_t size, void* ptr) throw();

the operator version new

. Here's what cplusplus.com has to say about this operator:

This is a version of the allocation that does not allocate memory - it just returns ptr. Note that the constructor of the object (if any) will still be called by the operator expression.



So this means mem and ptr will always be the same. I think it is a bad idea to keep both of them and it is better to use void* operator new (std::size_t size) throw (std::bad_alloc);

the operator version new

for example. in your case A* ptr = new A;

:;

+1


source







All Articles