0

I have a doubt related to the pasted code. I have allocated memory for an int and deleted(as usual). But somewhere i see this sysntax(line 1) which allocates an anonymous int space. How to free this space, isn't this result in memory leak?

main(){
  int *p = new int;
  new int;

  if(p)
   delete p;
  system("PAUSE");
  return 0;
}
Appleshell
  • 7,088
  • 6
  • 47
  • 96
instance
  • 1,366
  • 15
  • 23
  • 3
    You do not need to check `if(p)`. `delete` can handle `NULL` pointers. – tillaert May 21 '14 at 13:33
  • my doubt is it frees the memory which was allocated for p, but what about the memory allocated in "new int" or "new int" doesn't allocate any memory? – instance May 21 '14 at 13:33
  • You do not store the pointer, so you cannot free it. It's not unavoidable, if you store the pointer. – tillaert May 21 '14 at 13:34
  • Since the allocation is pointless, a memory leak is easily avoided by removing that line. – molbdnilo May 21 '14 at 13:39
  • Let's see... if you leak memory on purpose then it is unavoidable as far as the language is concerned(imho). The compiler could realise that it is pointless and optimize it away however. – r_ahlskog May 21 '14 at 13:57

2 Answers2

14

If you allocate memory, and deliberately choose not to hold a pointer to it, then you cannot free it.

C++ gives you enough rope to hang yourself with, and allows you to aim a gun at your own foot.
That is nothing new.


The other mistake is checking the value of p to see if it was allocated successfully.
Only on older compilers does new return NULL if it fails. On newer compilers, a failed new will result in throwing a std::bad_alloc exception.

So in this code, (assuming you are using a compiler from the last decade) you know that either:

  • the new succeeded, and p is valid/non-NULL.
  • or an exception was thrown.

There is no way for p to end up NULL!

Even if p could end up NULL, calling delete on a NULL value is perfectly safe, and there is nothing wrong with it.

So your example code could well be:

int main()
{
  int *p = new int;  // Will throw exception if fails

  new int;           // Deliberate Mem Leak

  delete p;          // No need to check NULL
  system("PAUSE");   // Pause to see results (NOTE: this is skipped if an exception is thrown!)
  return 0;         
}
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • i am not sure though, but i have read somewhere that deleting a null or un-allocated space is an undefined behaviour. – instance May 21 '14 at 13:39
  • @user3312772 deleting a null pointer should not result in undefined behaviour I believe – EdChum May 21 '14 at 13:40
  • 1
    @user3312772 `delete NULL;` is well defined. See [this previous question](http://stackoverflow.com/a/6177338/311966) or [docs for operator delete](http://www.cplusplus.com/reference/new/operator%20delete[]/) for details. Deleting a non-NULL address that you didn't allocate would indeed result in undefined behaviour. – simonc May 21 '14 at 13:46
  • 2
    yeah my bad, deleting NULL is safe indeed. – instance May 21 '14 at 13:46
0

Well, this is C++, so unavoidable is a (slight) overstatement.

"All" you need to to is replace global operator new, and have that keep track of allocations. Now: I can't imagine doing this is real code, but doing the equivalent for class types only is something done in practice (although I don't imply that it's best practice!)

For example, this (otherwise quite silly) code does not leak .

int count = 0;
void* operator new (size_t size)throw(std::bad_alloc)
{
    if (size == sizeof(int))
    {
        ++count;
        if (count == 2)
            return &count;
    }
    return malloc (size);
}

void operator delete (void *p)throw()
{
    if (p != &count)
        free(p);
}

int main()
{
    int *p = new int;
    new int;
    delete p;
    system("PAUSE");
    return 0;
}
Keith
  • 6,756
  • 19
  • 23
  • from this code you mean to say...you will not allocate space for second line (new int)....right? – instance May 22 '14 at 08:38
  • well, not allocate any heap, but still return the address of some pre-allocated storage for an int. That is not important; the key thing is that you can take total control of allocation and deallocation. For example, you _can_ (but please don't) implement your own garbage collection. – Keith May 22 '14 at 23:17