How to Call a Constructor on an Already Allocated Memory

How to call a constructor on an already allocated memory?

You can use the placement new constructor, which takes an address.

Foo* foo = new (your_memory_address_here) Foo ();

Take a look at a more detailed explanation at the C++ FAQ lite or the MSDN. The only thing you need to make sure that the memory is properly aligned (malloc is supposed to return memory that is properly aligned for anything, but beware of things like SSE which may need alignment to 16 bytes boundaries or so).

C++, is it possible to call a constructor directly, without new?

Sort of. You can use placement new to run the constructor using already-allocated memory:

 #include <new>

Object1 ooo[2] = {Object1("I'm the first object"), Object1("I'm the 2nd")};
do_smth_useful(ooo);
ooo[0].~Object1(); // call destructor

new (&ooo[0]) Object1("I'm the 3rd object in place of first");

So, you're still using the new keyword, but no memory allocation takes place.

Constructor called on an already created object

First off, the [c] tag is inappropriate since constructors are a C++-only feature. I'll assume the code snippet you provided is in fact C++ and not some weird dialect of C. C++ and C are different languages; do not tag your questions as both since you will get different answers for each.

Second, your constructor definition is wrong. Constructors must have the exact same name as the class itself. So f() should've been F(). Yes, case-sensitivity matters in C++! I'll assume this is what you meant for the rest of the code snippet. OP simply made a typo.

Before I explain what the rest of your code does, you must understand that all classes (and structs) in C++ have special member functions that are automatically generated by the compiler if you don't provide them. That is, your code snippet is basically the same as:

struct F
{
F(int _a, int _b) {a = _a; b = _b}; // constructor
~F() {} // destructor
F(const F& rhs) // copy constructor
: a(rhs.a)
, b(rhs.b)
, c(rhs.c)
, d(rhs.d)
{}
F& operator=(const F& a) // copy assignment operator
{
a = rhs.a;
b = rhs.b;
c = rhs.c;
d = rhs.d;
return *this;
}

void a(int _a, int _b) {a = _a; b = _b}; // one of your functions

int a;
int b;
int c;
int d;
};

If you do not define a copy constructor, a copy assignment operator, or a destructor, the compiler will generate them for you. Also, if you don't provide some other constructor, the compiler will generate a default constructor. There is no default constructor for class F since there's already a (non-copy) constructor that accepts two arguments.

The default implementation of the copy constructor and the copy assignment operator simply copies each data member.

The reason why special member functions exist is because C++ generalizes the notion of copying primitive types to user defined objects. Consider this:

int a = 42;
int b = 13;
b = a;

With primitive types like ints, you can copy around its value just like that. C++ generalizes the copy semantics to objects so you can do this:

F f(10, 20); // calls first constructor
F g(30, 40); // calls first constructor
g = f; // calls g's copy-assignment operator.

Now you can see how this applies to your code:

F f = F(5,6); 

The line above constructs a temporary F object, then copies the temporary into f via the copy constructor. The temporary F object is then destructed.

f = F(7,8);

The line above constructs another temporary F object, then assigns the temporary into f via the copy assignment operator. The temporary F object is then destructed. The original f object is not destructed.

f.a(9,0)   

The line above is a normal function call on an object called f.

For your code snippet, assuming compilers do not optimize away the temporaries (they in fact usually do), then calling the function a is "less resource intensive" since no temporaries are made in that case. However, for your first constructor call, you can just do this:

F f(5,6); // Constructor called; no temporaries are made

Understand what constructors are used for: they are used to create objects. If you already have an object, then you don't need to call a constructor.

As I have recommended many times, please pick up a good C++ book and read it. Special member functions and what they do are quite fundamental to C++.

How to call the constructor on a std::queue that's in a structure that's already allocated

Yes, that is how you do it. Not only for std::queue<> but for any object you want to construct on a preallocated buffer.

In your case, since the std::queue<> is part of a struct, constructing a QueueData object this way will ensure its member m_queue is constructed as well. Bear in mind this constructor may allocate memory.

Don't forget to call the destructor explicitly before deallocating the buffer, otherwise you'll leak the memory allocated on the constructor, or during the normal operation of the std::queue. E.g:

pData->~QueueData();
somethingThatDeallocatesTheBuffer(pData);

Memory allocation and constructor

First of all, from a language standard perspective, you cannot access the object's storage outside of the lifetime of the object. Before the object is created, you do not know where the object is located, and after it has been destructed, accessing the storage yields undefined behavior. In short: A conforming C++ program cannot observe the difference of when the storage is allocated.

Automatic storage typically means "on the call-stack". I.e. allocation happens by decrementing the stack pointer, and deallocation happens be re-incrementing it. A compiler could emit code that does the stack pointer adjustments exactly where the lifetime of the object starts/ends, but this is inefficient: It would clutter the generated code with two extra instructions for each object that is used. This is especially a problem with objects that are created in a loop: The stack pointer would jump back and forth between two or more positions constantly.

To improve efficiency, compilers huddle all possible object allocations together into a single stack frame allocation: The compiler assigns an offset to each variable within the function, determines the max. size that is required to store all the variables that are present within the function, and allocates all the memory with a single stack pointer decrement instruction at the start of the function execution. Cleanup is then the respective stack pointer increment. This removes any allocation/deallocation overhead from loops as the variables in the next iteration will simply reuse the same spot within the stack frame as the previous iteration used. This is an important optimization, for many loops declare at least one variable.

The C++ standard does not care. Since use of the storage outside of an object's lifetime is UB, the compiler is free to do with the storage whatever it pleases to do. Programmers should not care as well, but they do tend to care about their programs execution times. And that's what most compilers optimize for by using stack frame allocation.

Calling the constructor from the assignment operator

Well, in GCC both are not allowed. My guess is that if your compiler allows one but not the other, then it is to avoid disambiguation.

When you write this->Arr(), the compiler cannot know that you meant to call the constructor, rather than just instantiate a new object.

When you write this->Arr::Arr(), then the compiler knows that you call the static function Arr() of the class Arr.

Calling a constructor to re-initialize object

Sort of. Given a class A:

A a;
...
a = A();

the last statement is not initialisation, it is assignment, but it probably does what you want.



Related Topics



Leave a reply



Submit