5

I am trying to understand memory part in C++. I am trying to release memory after I generate the output by using the code below.

Question:

Is it necessary to release memory by using if-statement?

Code:

int main(){
    char *pc;
    int *pi;

    pc = new char('a');
    pi = new int(8);

    cout << *pc << endl;
    cout << *pi << endl;

    //What's the purpose for doing if(pc) and if (pi) below?

    if(pc){
        delete pc;
    }
    if(pi){
        delete pi;
    }

return 0;
}

Could I be able to do in this way? int main(){ char *pc; int *pi;

    pc = new char('a');
    pi = new int(8);

    cout << *pc << endl;
    cout << *pi << endl;


    delete pc;
    delete pi;

return 0;
}
14K
  • 399
  • 1
  • 3
  • 15
  • 8
    No, delete performs the null check itself. See this -> http://stackoverflow.com/a/4190737/1898811 –  May 16 '13 at 22:46
  • 4
    Obligatory smart pointer reference. If you use them, you don't have to worry about any of this. – chris May 16 '13 at 22:47

3 Answers3

9

Is it necessary to use IF statement when releasing memory?

No, it is not (as long as you haven't overridden the global operator delete). This is perfectly fine and will do nothing:

int* p = nullptr;
delete p;

Per paragraph 3.7.4/2 of the C++11 Standard:

[...] The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. [...]

As suggested by chris in the comments, however, consider using smart pointers rather than performing manual memory management through raw pointers, new, and delete (or their array counterpart).

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
3

In your particular code, the null checks are not needed.

In general, it's implementation specific whether delete (T*)0; will call the deallocation function for type T. If your implementation does pass null pointers to the deallocation function, and either your type has overridden the deallocation function by providing member operator delete, or you're provided a replacement global ::operator delete, and that custom deallocation function doesn't handle null pointer values well, you could have trouble.

The Standard does NOT require that a custom operator delete do nothing when passed a null pointer. It shouldn't fail, but it might write nasty log messages or tell your boss that someone isn't following the coding standard, for example.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • +1 for mentioning custom delete – Steve May 16 '13 at 23:06
  • If my implementation doesn't pass null pointers to the deallocation function, would the deallocation function still be called? – 14K May 16 '13 at 23:43
  • @Ming: Well it can't pass a different pointer to the deallocation function. If you write `delete (p)` and `p` is null, then the compiler either will call `operator delete(p)` or nothing at all. If `p` is not null, then the compiler certainly will call the destructor and then `operator delete(p)` – Ben Voigt May 17 '13 at 00:33
  • @BenVoigt so in this case I could just do delete(pc); delete(pi) then will be all good right? – 14K May 17 '13 at 01:05
  • 1
    @Ming: You can definitely do `delete pc; delete pi;` because it's impossible for them to be null in the first place. – Ben Voigt May 17 '13 at 01:58
  • @BenVoigt So what's the point to do delete nullptr;? since delete performs null check itself? – 14K May 17 '13 at 02:09
  • Well, sometimes you have a variable that might or might not be null. But yours can't be. – Ben Voigt May 17 '13 at 02:13
-1

No it's not but it's considered a good practice to do so. In real life scenario your code changes frequently due to business requirements, bugs, etc so it's always best to use this kind of defensive programming strategy.

The last thing you want is having a hard-to-detect error due to freeing already freed pointer because your colleague changed the upper portion of the code

gerrytan
  • 40,313
  • 9
  • 84
  • 99
  • 2
    Forgetting this check can't lead to double-freeing. It can only lead to free-ing null. Which does nothing. – djechlin May 16 '13 at 22:50
  • @djechlin agreed but I'm pointing out the fact about defensive programming strategy, not specific to the code snippet above – gerrytan May 16 '13 at 22:51
  • 1
    It doesn't defend against anything though. – djechlin May 16 '13 at 22:51
  • Setting a pointer to NULL after you delete it is not a horrible idea, if you must use naked pointers. – Retired Ninja May 16 '13 at 22:51
  • 1
    Basically it's a remnant of C programming where it *is* good practice. But in C++ it does nothing besides make the code look more C-like. I do not consider this good practice nor know anyone who does; to me all this looks like is C code that was written by someone who doesn't understand C++ or didn't bother to learn the language or coding styles properly. – djechlin May 16 '13 at 22:55
  • 1
    Setting a pointer to null after freeing it gives a false sense of security. `int *p = new int; int *q = p; delete p; p = 0;` Now, `if(q)` won't help. Code to properly handle pointer and memory management is something you **design**, not something you stick in because some rubric said you should. "Defensive" programming is no substitute for sound design. – Pete Becker May 16 '13 at 23:40
  • *"it's considered a good practice to do so"* - I've never heard this being called *"good practice"* (well ok, now I have). And checking against `nullptr` would detect double freeing (hint: no, it wouldn't)? – Christian Rau May 17 '13 at 07:41