Anything allocated with new should have a delete?

Note the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
struct Foo
{
    int abc = 2;
    float def = 3.0f;
    double ghi = 45.0;
};

unsigned char* memory = (unsigned char*)malloc(sizeof(Foo));

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

free(memory);


I know that foo will be inacessible because I freed the memory that was used on the new operator, but should I have to use 'delete' on anything that I use 'new' ? is it mandatory? Or should I use new and delete on the memory pointer as well ?

Also if anyone has any alternative to an allocation that brings the initialized values I wrote directly on the struct I would appreciate, because I don't know if the new operator does anything else other than just initializing the values with the custom memory block I passed to it

PS.: I'm just using the new operator with a custom memory on the Foo struct pointer because it takes into account the values initialized directly on the struct, using a zeroed memory block with malloc it will just have zero values, and I want to initialize the values on the struct.

Edited by khofez on
Given that this is a trivially destructible type just freeing is enough.

However if there is a non-trivial destructor (either directly or one of its member fields) then you have to call the destructor on Foo before deallocating.

1
foo->~Foo();


You must understand that there are two "type" of new operators. One is that allocates memory and "calls" the constructor. Other one is placement new - this is the one you are using.

One the other end - delete does two things. Calls destructor and releases the memory. As you correctly understand you don't need to release memory, but you may want to call destructor depending on your types. rachetfreak shows you how to do this.

I want to initialize the values on the struct.

You could do this instead:
1
2
3
4
unsigned char* memory = (unsigned char*)malloc(sizeof(Foo));

Foo* foo = (Foo*)memory;
*foo = Foo();


I'm almost 100% sure it will generate exactly same instructions as long as your struct is POD.

Edited by Mārtiņš Možeiko on
Thank you very much!

I already knew about the two new operators but I did not know exactly what the placement new does, but it seems it just calls the constructor is that right?

And how does your example (*foo = Foo();) differs too much from the placement new calling the constructor? Like in performance, or is just the same?
khofez
Thank you very much!

I already knew about the two new operators but I did not know exactly what the placement new does, but it seems it just calls the constructor is that right?

And how does your example (*foo = Foo();) differs too much from the placement new calling the constructor? Like in performance, or is just the same?


That created a temporary and uses the (move) assignment operator to assign the values to the foo after which it destroys the temporary, for a Plain Old Data struct it doesn't make a difference after optimization.

For a non-POD struct that assumes the destination struct is already properly initialized. This matters when destructors and rule of 0/3/5 is in play.

Ummm, I see, so that is the only difference? Because I just plan to use the placement new and constructors only. So performance-wise it does not make any difference?
khofez
And how does your example (*foo = Foo();) differs too much from the placement new calling the constructor? Like in performance, or is just the same?


The difference is that it is less confusing for you :) If you do assignment, then there are no questions about calling delete or when/how/why to deallocate memory. There are no other differences for POD types. Generated machine code should be identical.

Edited by Mārtiņš Možeiko on
Cool! Well for me I find that the new placement is less confusing, but thats just my opinion haha, cause the assignment one you have to know the variable name to assign it, with the placement new is just one line haha

Thanks guys for the help :)
Here's the one line variant without introducing new variable:
1
*(Foo*)memory = Foo();