user3355815
user3355815

Reputation: 1

Is it possible to delete objects in a subfunction?

I have a problem with a memory leak in C++.

I create an object (new TYPE) and pass it to a subfunction. I know I have to delete the object in order to avoid memory leaks - but, when I call delete on the object within the subfunction, this causes a crash of the application:

void subfunction (TYPE* oldObject,....) {
    //deep-copy object
    TYPE* object = new TYPE(oldObject->p1,oldObject->p2,....)
    subfunction (object,....)
    delete oldObject
}

What is the problem here? Do I have to delete an object in the same function it was created in?

Am I not allowed to delete an object within a function, which was an argument to this function?

EDIT: the error message is '* Error in `./a.out': free(): invalid size: 0x00007fff4fbe59c0 *'

Upvotes: 0

Views: 137

Answers (5)

user3356452
user3356452

Reputation: 1

I am the thread opener; sadly my system crashed and I have not stored the trashmailaddress for the login, therefore I can answer now only as a new user

vonbrand actually gave the right hint. The first object was initialized with default values as

TYPE c; TYPE* cp =&c;

how is such an element deleted? probably automatically at the end of it's scope, which caused the second delete operation and thereby my problem.

Upvotes: 0

vonbrand
vonbrand

Reputation: 11791

The few lines you show don't allow to diagnose the problem at all. As the other answers and comments say, this is probably due to deleting an object twice, or perhaps deleting an object that wasn't given by new in the first place. Or it might be that some other code is trampling on your pointer, or straying outside the allocated object, and what delete finally sees is corrupted.

In C++ there are lots of things you are can do, not all of them necessarily good ideas. And memory management is tricky. You can leave much of it to the language (using containers, smart pointers, and so), or you can look for one of the garbage collection add-ons.

If you want to do it by hand, define carefully the following points:

  1. Who is in charge or creating each type of object? Hopefully a short list.
  2. What are users allowed to do to the object? Better make this as uniform as possible.
  3. Who is in charge of disposing of the object? Again, hopefully a short list.
  4. Make sure each object is created once and destroyed once on each possible path though your code (i.e., match up (1) and (3), ensure (2) doesn't meddle with this)
  5. Think carefully about each strech of code where there are several pointers to the same object. Which of them "owns" the object, is "owership" cleanly handed over from one to the next if needed? Does this mesh well with (1) and (3) above? Could it confuse some of (2) if several different pointers to the same object get passed?

Set up general rules across all object types if possible (to have to remember different rules guarantees you'll apply the wrong ones eventually, and get fireworks as a result). Some simple rules are as given above (new/delete in the same scope, for instance; make sure new is called only in constructors, delete only in destructors another), but they can be too restrictive (objects on the heap and pointers are great precisely because the lifetimes of the objects don't have to match up with the code).

Consider using memory allocation tracing/debugging tools, like valgrind. But do not depend on them, finding a mess and cleaning it up is much more work than a bit of planning beforehand. And you might not notice the mess in your tests, while Murphy's law assures you it will crash or otherwise misbehave at the worst possible time.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254431

What is the problem here?

You're probably deleting the same object twice. It's easy to do that when you're throwing pointers around and hoping something deletes it at the right time.

Do I have to delete an object in the same function it was created in?

You can delete it anywhere (as long as you do it exactly once). You shouldn't, since juggling pointers makes it almost impossible to ensure you do it exactly once.

Am I not allowed to delete an object within a function, which was an argument to this function?

You're allowed to; but you shouldn't, since the caller will be left with a dangling pointer. If it tries to do anything with it after the object's been deleted, then all kinds of wrongness can ensue.

Avoid new unless you really need it; and use smart pointers to manage everything you create with new. Then you can get on with writing useful code instead of debugging a wobbly heap of memory corruption.

Upvotes: 2

stefaanv
stefaanv

Reputation: 14392

The problem with memory management is that although it is basically rather easy (new/new[] -> delete/delete[]), it becomes tricky when the program becomes more complex.

That is why the first advise is to avoid memory management. This can be done by declaring objects instead of pointers and by using standard library containers.

If needed, use RAII to handle memory management (clean up in destructor), most notably smart pointers (std::unique_ptr, std::shared_ptr).

When doing memory management by using (new/delete), allocate and free memory in the same scope, so it is easier to track good usage.

If it is really necessary, delete can be done in other scopes, like functions, but it can become very difficult to manage.

So in the code in your question, there is nothing that directly points to crash, so it has to be in combination with code that you didn't show.

Upvotes: 0

prmottajr
prmottajr

Reputation: 1824

The problem is that, you are probably refering to oldObject on its original place right after the call to subfunction (the original call).

Cheers.

Upvotes: 0

Related Questions