handmade.network » Forums » Anything allocated with new should have a delete?
khofez
21 posts
#15846 Anything allocated with new should have a delete?
3 months, 3 weeks ago Edited by khofez on July 23, 2018, 5:35 p.m.

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.
ratchetfreak
412 posts
#15847 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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();


mmozeiko
Mārtiņš Možeiko
1826 posts / 1 project
#15848 Anything allocated with new should have a delete?
3 months, 3 weeks ago Edited by Mārtiņš Možeiko on July 23, 2018, 5:46 p.m.

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.
khofez
21 posts
#15849 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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?
ratchetfreak
412 posts
#15850 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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.

khofez
21 posts
#15851 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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?
mmozeiko
Mārtiņš Možeiko
1826 posts / 1 project
#15852 Anything allocated with new should have a delete?
3 months, 3 weeks ago Edited by Mārtiņš Možeiko on July 23, 2018, 8:09 p.m.

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.
khofez
21 posts
#15853 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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 :)
mmozeiko
Mārtiņš Možeiko
1826 posts / 1 project
#15855 Anything allocated with new should have a delete?
3 months, 3 weeks ago

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