Why do I need to delete[]?

2019-01-21 18:26发布

Lets say I have a function like this:

int main()
{
    char* str = new char[10];

    for(int i=0;i<5;i++)
    {
        //Do stuff with str
    }

    delete[] str;
    return 0;
}
  1. Why would I need to delete str if I am going to end the program anyways? I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?

  2. Is it just good practice?

  3. Does it have deeper consequences?

15条回答
看我几分像从前
2楼-- · 2019-01-21 19:12

I cannot agree more to Eric Lippert's excellent advice:

So the answer to the question "should I free memory before my program exits?" is "it depends on what your program does".

Other answers here have provided arguments for and against both, but the real crux of the matter is what your program does. Consider a more non-trivial example wherein the type instance being dynamically allocated is an custom class and the class destructor performs some actions which produces side effect. In such a situation the argument of memory leaks or not is trivial the more important problem is that failing to call delete on such a class instance will result in Undefined behavior.

[basic.life] 3.8 Object lifetime
Para 4:

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

So the answer to your question is as Eric says "depends on what your program does"

查看更多
smile是对你的礼貌
3楼-- · 2019-01-21 19:12

It's a fair question, and there are a few things to consider when answering:

  • some objects have more complex destructors which don't just release memory when they're deleted. They may have other side effects, which you don't want to skip.
  • It is not guaranteed by the C++ standard that your memory will be released when the process terminates. (Of course on a modern OS it will be freed, but if you were on some weird OS which didn't do that, you'd have to free your memory properly
  • on the other hand, running destructors at program exit can actually take up quite a lot of time, and if all the do is release memory (which would be released anyway), then yes, it makes a lot of sense to just short-circuit that and exit immediately instead.
查看更多
成全新的幸福
4楼-- · 2019-01-21 19:16

Important note : delete's freeing of memory is almost just a side-effect. The important thing it does is to destruct the object. With RAII designs, this could mean anything from closing files, freeing OS handles, terminating threads, or deleting temporary files.

Some of these actions would be handled by the OS automatically when your process exits, but not all.

In your example, there's no reason NOT to call delete. but there's no reason to call new either, so you can sidestep the issue this way.

char str[10];

Or, you can sidestep the delete (and the exception safety issues involved) by using smart pointers...

So, generally you should always be making sure your object's lifetime is properly managed.

But it's not always easy: Workarounds for the static initialization order fiasco often mean that you have no choice but to rely on the OS cleaning up a handful of singleton-type objects for you.

查看更多
叛逆
5楼-- · 2019-01-21 19:17

new and delete are reserved keyword brothers. They should cooperate with each other through a code block or through the parent object's lifecyle. Whenever the younger brother commits a fault (new), the older brother will want to to clean (delete) it up. Then the mother (your program) will be happy and proud of them.

查看更多
叼着烟拽天下
6楼-- · 2019-01-21 19:18

Another reason that I haven't see mentioned yet is to keep the output of static and dynamic analyzer tools (e.g. valgrind or Coverity) cleaner and quieter. Clean output with zero memory leaks or zero reported issues means that when a new one pops up it is easier to detect and fix.

You never know how your simple example will be used or evolved. Its better to start as clean and crisp as possible.

查看更多
啃猪蹄的小仙女
7楼-- · 2019-01-21 19:20

Yes it is good practice. You should NEVER assume that your OS will take care of your memory deallocation, if you get into this habit, it will screw you later on.

To answer your question, however, upon exiting from the main, the OS frees all memory held by that process, so that includes any threads that you may have spawned or variables allocated. The OS will take care of freeing up that memory for others to use.

查看更多
登录 后发表回答