-3

What's good and what's wrong? In which case do I have to call delete in order to prevent memory leak? Also, is the behaviour exactly the same in C and C++? Are there any differences?

const char* a = "blahblah";
...
delete a;

char b* = new char('a');
...
delete b;

char c[100] = "blahblah";
...
delete c;

char d* = new char[40];
...
delete d;

char e* = new char[40];
...
delete[] e;
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mmmh mmh
  • 5,334
  • 3
  • 21
  • 29

7 Answers7

11

In which case do I have to call delete in order to prevent memory leak

Only delete what you got from new and delete [] what you got from new []. Every other delete is wrong.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 1
    Could the downvoter please provide some insight ? I'm just a beginner so I could have made some silly mistakes / assumptions. Would really appreciate it :-) – cnicutar Feb 21 '13 at 20:03
  • 4
    I can assure you that the downvoter is either wrong about C++, or on drugs. – Lightness Races in Orbit Feb 21 '13 at 20:07
  • 1
    (Beginner? Really? Mr 70.7k-rep C++ gold badge) – Lightness Races in Orbit Feb 21 '13 at 20:07
  • 1
    @LightnessRacesinOrbit I don't really know much C++. I seriously think most of the C++ rep was from mistagged questions :-/ – cnicutar Feb 21 '13 at 20:08
  • I downvoted your answer because it implies that using `new` and `delete` yourself is correct, which it is not. – Puppy Feb 21 '13 at 20:12
  • @DeadMG You're right, a client should never use `new`. I think I read about it sometime.. can you provide a link ? – cnicutar Feb 21 '13 at 20:14
  • @LightnessRacesinOrbit I'm pretty serious, when reading C++ code I have frequent "does that even compile?" moments. – cnicutar Feb 21 '13 at 20:16
  • 1
    @DeadMG: You downvoted a perfectly accurate answer because of a loose inference? That's poor. – Lightness Races in Orbit Feb 21 '13 at 20:16
  • @cnicutar: Bah, broken system! – Lightness Races in Orbit Feb 21 '13 at 20:20
  • @LightnessRacesinOrbit It is. SO rep says nothing about technical expertise. – cnicutar Feb 21 '13 at 20:21
  • There's nothing "loose" here. For the answer to be correct, it must be that if the OP follows his advice, he will get a correct program. That is not true with this answer, since it's basically impossible for the OP to actually perform this task without the aid of the compiler. Therefore, the answer cannot be correct, because the OP cannot create a correct program from this advice. – Puppy Feb 21 '13 at 20:21
  • 2
    @DeadMG: It's nonsensical to suggest that you cannot create a correct C++ program if you write `new` and `delete`. The OP cannot use these basic keywords "without the aid of the compiler"? Are you on drugs? – Lightness Races in Orbit Feb 21 '13 at 20:34
3

The rules are simple:

  • Do not delete any pointer for which you did not call new
  • Use delete[] for everything that you allocated with new[]
  • Use delete (no brackets) for everything that you allocated with new (no brackets)

By following these rules you can see that only the deletions of b and e are valid:

  • a and c have not been allocated with a new
  • d needs a delete[]
  • b and e are correct.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

They're all wrong. Do not ever call delete in a C++ program (unless you are directly implementing a memory-managing primitive, like smart pointer)- always use a smart pointer to handle resource destruction. For arrays, use a container like std::vector<T>. For strings, there is a dedicated std::string class. Finally, there are no primitive situations except new that create objects suitable for delete, whether directly or correctly (through a smart pointer), so if you did not use new or call a function that explicitly returns such (which should really return a smart pointer...), then you're definitely doing it wrong.

  1. Wrong because there's no dynamic memory to delete.
  2. Wrong because you should use smart pointer (unique_ptr looks fine here).
  3. Same as 1.
  4. Wrong because you need std::vector for dynamically allocated arrays.
  5. Same as 4.
Puppy
  • 144,682
  • 38
  • 256
  • 465
  • I am pretty certain that this is a learning exercise to spot intolerable "wrongs" that tend to crash your program, as opposed to "tolerable" ones, when you know that your program is bad, but it does not crash (i.e. the most common variety of programs out there). – Sergey Kalinichenko Feb 21 '13 at 20:04
  • I agree with this more than with that http://stackoverflow.com/a/15011082/1582182 . – Mmmh mmh Feb 21 '13 at 20:05
  • What do you mean by "user mode"? I assume you do not mean user mode vs. kernel mode? ;) – hyde Feb 21 '13 at 20:07
  • 1
    And we're back to this again. This answer is just as dangerous as the last one where you wrote "do not ever call `delete`" and then left the qualifying comments in technical-speak. If you wrote "do not ever call `new` or `delete`" then it would be safer, but you can't. – Lightness Races in Orbit Feb 21 '13 at 20:08
  • @hyde: I guess he means outside of a library, in the space where you do your "actual" programming. For example, the smart pointer implementations are "allowed" to use `delete` and then, because those exist, _you_ do not need to... unless you're writing one of those implementations. – Lightness Races in Orbit Feb 21 '13 at 20:09
  • I have explicitly stated "Use a smart pointer to handle resource destruction.". What more do you want me to write? It is more correct than the other answer, which is "PLEASE DOUBLE DELETE MY BUFFERS". – Puppy Feb 21 '13 at 20:13
  • @DeadMG: None of the answers says that. – Lightness Races in Orbit Feb 21 '13 at 20:17
  • 1
    There are plenty of cases for calling delete in an application "business" code, for example when the pointer is "owned" by library code, which may also delete it (an example is Qt and it's various classes where object commonly has a parent). And saying that using such a library is wrong is a bit strong statement. – hyde Feb 21 '13 at 20:17
  • @hyde: Even if you get an object back from a Qt function that Qt wants you to delete, there is no excuse for not immediately placing it in a smart pointer. – Puppy Feb 21 '13 at 20:22
  • @DeadMG But that's just it, you don't get a parented object "back", you just have it there, and then can also just `delete` it in the *rare* cases where you want it gone before its parent (virtual destructor will take care of cleanup), and putting it to smart pointer first just makes no sense. Anyway, my point is, saying "never call delete in application code" is demonstrateably wrong. But I do agree it's something to be avoided, when not mandated by external factors like library design. – hyde Feb 21 '13 at 20:48
  • They're not all wrong. Some are but while the others are no longer good practice, that's NOT the same as being definitively wrong. – Gwyn Evans Feb 21 '13 at 23:41
2

Also, is the behaviour exactly the same in C and C++? Are there any differences?

There is no delete in C, nor does C have new. Only free, which corresponds with malloc.

2

Three rules to follow:

  1. new goes with delete;
  2. new[] goes with delete[];
  3. If you want to write safe, robust, idiomatic code in 2013 and beyond, use smart pointer implementations (the result of which is that you will use new in your smart pointer constructor arguments, and then not use delete).
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Rule is that if you new/new[] then you have to use corresponding delete/delete[].

Mahesh
  • 34,573
  • 20
  • 89
  • 115
1
delete b;
delete[] e;

These are the only correct deletions.

As a rule of thumb:

  • for each new there should be a corresponding delete
  • for each new … [] there should be a corresponding delete []

These rules don't take exception-handling into consideration. To keep your code exception safe, use smart pointers. And use std::string when you mean "string".

johnsyweb
  • 136,902
  • 23
  • 188
  • 247