Is this considered a memory leak?

Let's assume you have a simple class:

class foo{
private:
    int* mData;
    int  mSize;
public:
    foo(int size){
        mSize = size;
        mData = new int [mSize];
    }
    ~foo() {
        mSize = 0;
        delete [] mData;
    }
};

      

Then inside the main one:

int main () {
    static int HUGE = 100000000;
    foo a(HUGE);
    // do something useful with a
    // .
    // .
    // .
    // Now I'm done with a; I do not need it anymore ...
    foo b(HUGE);
    // do something useful with b
    // Ok we are done with b
    return 0;
}

      

As you can see, it is a

no longer required after b

, but since it is created on the stack, the destructor will not be called until the end of the program. Now I know that this is not the same as allocating with help new

and forgetting to call delete

, however it still wastes memory. Do you think this is a "memory leak" or just bad programming?

Also, how would you avoid situations like this? One way would be to manually call the destructor when the object is no longer needed, but aside from looking ugly and unfamiliar !, you run into trouble double free

if you don't change the destructor to something like:

foo::~foo(){
    if (mData != NULL){
        delete [] mData;
        mData = NULL;
        mSize = 0;
    }
}

      

Another way is to create a

on the heap through foo *pa = new foo (HUGE)

and then call delete pa

after the object is no longer needed. It works, but in danger of introducing another possible memory leak (if you forget to call delete pa

).

Is there a better way to get rid of unwanted objects?

+3


source to share


10 replies


Destructors are called when an object goes out of scope. C ++ allows arbitrary scopes within function bodies. Write your main function like this:

int main () {
    static int HUGE = 100000000;

    {
        foo a(HUGE);
        // do something useful with a
        // Now I'm done with a; I do not need it anymore ...
    }

    {
        foo b(HUGE);
        // do something useful with b
        // Ok we are done with b
    }
    // etc.
    return 0;
}

      



I see that your example is oversimplified, but in a real program, don't forget either

  • implement an appropriate copy constructor operator=

    for and for foo

    or
  • add a declaration for the private copy constructor and operator=

    so that it cannot be called.
+10


source


Just put your huge a and b objects in your own curly braces if you're concerned about volume.

And this is not technically a memory leak, but it is very poor memory management as you stated.




{
  {
    foo a(HUGE);
  }
  ...

  {
    foo b(HUGE);
  }

      

+3


source


No, this is definitely not a memory leak.

A memory leak is when you allocate memory and you lose its handle, so you cannot release it afterwards. It doesn't matter where and when you free memory, as long as you do it.

You can add a closing area to free memory:

{
    foo a(HUGE);
}
{
    foo b(HUGE);
}

      

+1


source


This is not a memory leak because you do not lose track of the allocated memory . However, this is a little inefficient, especially when the program runs longer and should be avoided.

You can use scopes to shorten the lifetime of an object:

int main () {
    static int HUGE = 100000000;
    {
        foo a(HUGE);
        // do something useful with a
        // .
        // .
        // .
        // Now I'm done with a; I do not need it anymore ...
    }
    {
        foo b(HUGE);
        // do something useful with b
        // Ok we are done with b
    }
    return 0;
}

      

In addition, it is worth reconsidering whether these two pieces of code should be in separate functions, then the allocated objects will be freed when the function returns.

+1


source


The class constructor can also take the block of memory that you allocated as a parameter in your main () function. Thus, once "a" is executed using a block of memory, you can also pass it to "b". The "foo" destructor doesn't need to release any memory at all, and you don't need to worry about wasting memory or object lifetime at all.

+1


source


Do you think this is a "memory leak" or just bad programming?

No, this is not a memory leak.

How would you avoid situations like this?

Write small functions, a few lines. Your code will be more readable and an unused variable allocated on the stack will be freed.

0


source


This is not a memory leak; however, this is exactly what Firefox developers memory has been using for a long time.

This is most likely the easiest way to fix it, as Dark Falcon suggests . Alternatively move the selection and associated code to separate functions.

It is also safer to handle pointers by using std::auto_ptr

them to be freed when the area is freed.

0


source


Do you think this is a "memory leak"

Not unless you do something like longjmp in the middle.

or just bad programming?

I am considering using new [] to allocate an array in your bad programming practice because you have a std :: vector for that.

Also, how would you avoid situations like this?

Include foo in scope:

{
    foo a(HUGE);
}

      

unless you change the destructor to something like:

delete ignores null pointers. The destructor is called only once, so there is no need for null variables. Calling the destructor manually is a VERY BAD IDEA - not meant to be. If you want to reinitialize the structure, use the clear () or resize () methods.

Is there a better way to get rid of unwanted objects?

Yes, attach them to areas.

0


source


It's not a memory leak, but if you have a variable that you want the first half of the function and not the second, chances are good that the function does a lot and needs to be refactored into two (or more) separate functions.

0


source


Extract functions for volume reduction. Give them good names:

void do_a(int amount)
{
    foo a(amount);
    // ask `a` to be useful
}

void do_b(int amount)
{
    foo b(amount);
    // ask `b` to be useful
}

int main () {
    static int HUGE = 100000000;

    do_a(HUGE);
    do_b(HUGE);

    return 0;
}

      

0


source







All Articles