-2

I have the following below code snippet

class test{
    private:
        int *ptr;
    public:
        test(int *myptr){
            ptr = myptr;
        }
        ~test(){
            delete ptr;
        }
};

int main(){
    int* myptr = new int;
    *myptr = 10;
    test obj(myptr);
    delete myptr;
}

Is there a memory leak happening in this program, if I dont do a new to pointer in the class will space be allocated for that pointer?

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 4
    The pointer will be `delete`d twice. – songyuanyao Mar 18 '16 at 03:43
  • 3
    it shouldn't compile, you're not passing any input in the test() constructor – J-Mik Mar 18 '16 at 03:44
  • Just edited the problem, The question to consider is that if I am not creating a object using new, will space be allocated to the pointer in the class? – Manish Khilnani Mar 18 '16 at 03:47
  • @songyuanyao how will the pointer be deleted twice? – Manish Khilnani Mar 18 '16 at 03:48
  • 1
    @ManishKhilnani By the two `delete` statements in the code. The memory address the pointer points to is same. – songyuanyao Mar 18 '16 at 03:51
  • @songyuanyao, so does that mean that when I dont create an object using new memory is not allocated to the pointer of the class and it only points to myptr and deleting myptr will suffice and there will be no memory leak in the program? – Manish Khilnani Mar 18 '16 at 03:53
  • @ManishKhilnani Yes, memory won't be newed automatically. – songyuanyao Mar 18 '16 at 03:59
  • @ManishKhilnani I'd highly recommend taking a look at [some of these books](http://stackoverflow.com/q/388242/2069064). It'll be more helpful than asking this question. There's some fundamental concepts that need several pages of explanation - and some of those writers do an excellent job of explaining them! – Barry Mar 18 '16 at 04:00
  • You don't delete *pointers* (contrary to what @songyuanyao said) - you delete the objects they point to. – user253751 Mar 18 '16 at 04:19

8 Answers8

1

Rule of thumb for dealing with allocating member: every new/new[] should be paired with exactly one delete/delete[]. If you are missing the delete, then you have a memory leak (you have allocated memory that you never clean up). If you are delete-ing multiples times, as you are doing in this code example, you will have memory corruption issues.

How are you delete-ing multiple times? In main(), you allocate a pointer:

int* myptr = new int;

You give a copy of that pointer to your test object, obj. Then, at the end of the scope we have:

{
    // ...
    delete myptr;
    ~test(); // implicit, which also does delete myptr
}

Only one of those two places should be responsible for delete-ing the pointer. Which one is based on the semantics of your code. Does test own the pointer? In which case, it should delete it but main() should not. Does it simply observe the pointer? In which case, it should not delete it. With C++11, we have new smart pointers to express this idea better.

I'd encourage you to browse the definitive C++ book list as concepts like this are very crucial to understanding C++ but also very difficult to explain properly in a short Q&A format.

Community
  • 1
  • 1
Barry
  • 286,269
  • 29
  • 621
  • 977
0

You should only delte a pointer once in ~test() or delete directly

*** Error in `./a.out': double free or corruption (fasttop): 0x08d13a10 ***
Ezio
  • 1,116
  • 4
  • 13
  • 25
  • Yeah, I am not able to understand the concept here, if I only delete the pointer once that means memory for the private data member was not allocated? – Manish Khilnani Mar 18 '16 at 03:51
  • @ManishKhilnani delete is used to free `malloc` space , and ~test() is used to free obj(). You cannot free pointer two times. – Ezio Mar 18 '16 at 03:53
  • @Ezio: `delete` is used to delete allocations made from `new`. It is undefined behaviour to use `delete` for something that was returned from `malloc()`, and similarly, it is undefined behaviour to use `free()` for something that was obtained from `new`. – dreamlax Mar 18 '16 at 04:16
  • @dreamlax yes, so not to mix or redo. – Ezio Mar 18 '16 at 04:44
0

Consider using std::shared_ptr<int> or std::unique_ptr<int>, since direct memory management is discouraged in modern C++ unless you've a reason to do so. You can read about semantics differences of smart pointers here, and the reference for them is here.

Community
  • 1
  • 1
yuyoyuppe
  • 1,582
  • 2
  • 20
  • 33
0

What will happen in your instance is that the pointer will be given to delete in main(), then the same pointer value will be given a second time to delete in the destructor of obj. This is undefined behaviour, so it might work, or it might not, in any case, it isn't guaranteed to work, and therefore such a construct should not be used.

Ordinarily you would establish ownership rules, e.g. whether the constructor “takes ownership” (and is therefore responsible for freeing resources) is up to you, but typically, and especially in modern C++, ownership semantics can be clearly achieved by using std::unique_ptr and std::shared_ptr.

Most importantly, whichever method you use to determine ownership, make sure you are consistent! Avoid complicated ownership semantics, as it will make it much more difficult to detect memory-related issues (or more generally, resource-related issues).

dreamlax
  • 93,976
  • 29
  • 161
  • 209
0

It will crash when exit main function, a allocated in heap memory can't be release two times

Ming
  • 1,029
  • 1
  • 7
  • 5
  • This is a likely situation, but it isn't guaranteed to crash. Deleting a pointer twice is undefined behaviour. It may work, or it may not. – dreamlax Mar 18 '16 at 04:20
  • Or it may deallocate memory block which just was allocated by another thread at the same address. And then you will have hell of the time trying to understand what is happening :) – Ari0nhh Mar 18 '16 at 04:39
0

Contrary to what other people have said: you do not delete pointers in C++, but objects.

What's the difference?

Let's simplify your code a bit:

int *myptr = new int; // 1
int *ptr = myptr; // 2
delete myptr; // 3
delete ptr; // 4

As far as the usage of new and delete is concerned, this is the same code - I've just removed the class, since it's not relevant to the point here.

This code does the following:

  1. new int allocates an int, and returns its address. The address is then stored in myptr.

  2. The address is copied to ptr. Both ptr and myptr contain the address of the int that was just allocated.

  3. The int is deallocated.

  4. The int is deallocated... but it was already deallocated? Oops!

    If you're lucky, your program will crash at this point.

delete myptr; has nothing to do with the variable myptr, except that myptr holds the address of the thing to delete.

It doesn't even have to be a variable - you could do delete new int; (although it wouldn't be very useful) or delete someFunctionThatReturnsAnAddress();, or int *p = 1 + new int[2]; delete [] (p - 1);.

Community
  • 1
  • 1
user253751
  • 57,427
  • 7
  • 48
  • 90
-1

Your class has only a reference of the allocated integer. Consider to declare it int const* ptr, then you cant delete it inside the class. You should remove delete ptr from the destructor.

Usually the scope which is allocating something is responsible for freeing it. In your case the main routine is allocating and has to free.

Ari0nhh
  • 5,720
  • 3
  • 28
  • 33
caribes42
  • 47
  • 5
  • As a best practice after deletion always set the pointer to null. e.g. delete myptr; myptr = nullptr; // stable code ...later if( myptr ) delete ptr; // stable code – caribes42 Mar 18 '16 at 03:58
  • That doesn't change the fact that you can actually delete an `int const*`, which you claim to not be able to. Also, the class doesn't have a "reference" at all. It has a pointer. – Barry Mar 18 '16 at 04:08
  • 2
    @caribes42: `if (myptr) delete myptr;` is a useless construct, because if `myptr` is null, then `delete` will ignore it already. – dreamlax Mar 18 '16 at 04:14
  • yep, you are right. It should be: `if (myptr) {delete myptr; myptr=nullptr;}` Then its not useless. – caribes42 Mar 19 '16 at 06:47
-1

For your question "Is there a memory leak happening in this program", the answer is No, but an exception is rasing.

Your code logic is not good, you should delete the pointer at where it was created. In this example, you shouldn't delete ptr in destructor function.

Ronaldinho
  • 125
  • 1
  • 9