简体   繁体   中英

Do I have to delete pointer even if it is in function stack?

always delete pointer even if it is just in function call stack? Isn't it disappeared when function stack released?

// just Simple class
class CSimple{
  int a;
}

// just simple function having pointer.
void simpleFunc(){  
  CSimple* cSimple = new CSimple();
  cSimple->a = 10;
  //.. do sth
  delete cSimple;  // <<< Always, do I have to delete 'cSimple' to prevent the leak of memory?
}

void main(){
  for( int =0 ; i< 10 ; i++){
     simpleFunc();
  }

}

when function stack released?

It is true that "CSimple *csimple" goes away when the function returns.

However, there's a big difference between the pointer, and what it's pointed to.

When a pointer object gets destroyed, nothing happens to whatever the pointer is pointing to. There isn't just one, but two objects here:

  1. The pointer.

  2. What it's pointing to.

In this case, the pointer is pointing to an object in dynamic scope that was created with new .

Nothing is going to happen to this object, otherwise, so you will leak memory.

Therefore, this object needs to be delete d.

After you understand, and fully wrap your brain around this concept, your next step will be to open your C++ book to the chapter that talks about the std::unique_ptr and std::shared_ptr classes, which will take care of these pesky details, for you. You should learn how to use them. Modern C++ code rarely needs to delete something; rather these smart pointers do all the work.

Yes.

On scope exit (ex. when function exists or block { ... } finishes), all objects created on stack will be destroyed and memory will be freed.

This applies to your case, ie. the pointer will be destroyed and memory occupied by the pointer will be freed. The object pointed by the pointer will not be cleared.

This is a common problem and a nightmare when you deal with multiple flow paths (if-else ladders, many return statements) and exceptions.

To solve this problem, we employ 2 main strategies:

  1. RAII
  2. Smart pointers ( std::unique_ptr , boost::scoped_ptr , legacy std::auto_ptr , etc).

RAII - without academic consideration - is just creating object on stack, like this:

{
   std::string s;
   fancy_object obj;
}

When we exit he scope, obj and s destructors will be called duing stack unwinding. Compiler ensures this for all flow paths and will keep proper order of deallocations for us.

If you need to allocate memory on heap, using new , use a smart pointer.

int foo()
{
    std::unique_ptr<Object> o(new Object);
    ... some more code ...
    if( something ) { return -1 }
    ... some more code ...
    if( something_else ) { return -2 }
    else { not yet }
    return 0;
}

As you can see, we can leave the scope using 3 "exists". Normally, you'd need to clear your memory in all cases, which is prone to human errors.

Instead of clearing the object manually in all 3 palces, we rely on automatic destructor call for objects created on stack. Compiler will figure it out. When we leave the scope, std::unique_ptr destructor will be called, calling delete on Object .

Don't be affraid of smart poiners. They are not "slow", "bloat" or other nonsense. Smart poiners are designed to have no overhead on access, adding extra security.

Very similar technique is used for locks. Check out std::lock_guard class.

Yes, you must delete the data that is being pointed to.

The pointer itself is on the stack and does not need to be deleten.

You can, however, store cSimple on the stack, then you don't have to delete it:

void simpleFunc(){  
  CSimple cSimple; // no new
  cSimple.a = 10; // "." instead of "->"
  //.. do sth
  // no deletion
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM