Why do you have to call delete for local variables

2020-07-11 09:14发布

Suppose that you have the following function:

 void doSomething(){
    int *data = new int[100];
 }

Why will this produce a memory leak? Since I can not access this variable outside the function, why doesn't the compiler call delete by itself every time a call to this function ends?

6条回答
成全新的幸福
2楼-- · 2020-07-11 09:48

The whole point of dynamic allocation like this is that you manually control the lifetime of the allocated object. It is needed and appropriate a lot less often than many people seem to think. In fact, I cannot think of a valid use of new[].

It is indeed a good idea to let the compiler handle the lifetime of objects. This is called RAII. In this particular case, you should use std::vector<int> data(100). Now the memory gets freed automatically as soon as data goes out of scope in any way.

查看更多
Summer. ? 凉城
3楼-- · 2020-07-11 09:55

Here you have an int array dynamically allocated on the heap with a pointer data pointing to the first element of your array.

Since you explicitly allocated your array on the heap with new, this one will not be deleted from the memory when you go out of scope. When you go out of scope, your pointer will be deleted, and then you will not have access to the array -> Memory leak

查看更多
Bombasti
4楼-- · 2020-07-11 09:56

Actually you can access this variable outside of your doSomething() function, you just need to know address which this pointer holds.

In picture below, rectangle is one memory cell, on top of rectangle is memory cell address, inside of rectangle is memory cell value.

enter image description here

For example, in picture above, if you know that allocated array starts from address 0x200, then outside of your function you can do next:

int *data = (int *)0x200;
std::cout << data[0];

So compiler can't delete this memory for you, but please pay attention to compiler warning:

main.cpp: In function ‘void doSomething()’:
main.cpp:3:10: warning: unused variable ‘data’ [-Wunused-variable]
     int *data = new int[100];

When you do new, OS allocates memory in RAM for you, so you need to make OS know, when you don't need this memory anymore, doing delete, so it's only you, who knows when execute delete, not a compiler.

查看更多
我想做一个坏孩纸
5楼-- · 2020-07-11 09:57

Since I can not access this variable outside the function, why doesn't the compiler call delete by itself every time a call to this function ends?

Because you should not allocate memory on the heap that you wouldn't use anyway in the first place. That's how C++ works.

EDIT: also if compiler would delete the pointer after function returns then there would be way of returning a pointer from function.

查看更多
我命由我不由天
6楼-- · 2020-07-11 10:01

Why will this produce a memory leak?

Because you're responsible for deleting anything you create with new.

Why doesn't the compiler call delete by itself every time a call to this function ends?

Often, the compiler can't tell whether or not you still have a pointer to the allocated object. For example:

void doSomething(){
    int *data = new int[100];
    doSomethingElse(data);
}

Does doSomethingElse just use the pointer during the function call (in which case we still want to delete the array here)? Does it store a copy of the pointer for use later (in which case we don't want to delete it yet)? The compiler has no way of knowing; it's up to you to tell it. Rather than making a complicated, error-prone rule (like "you must delete it unless you can figure out that the compiler must know that there are no other references to it"), the rule is kept simple: you must delete it.

Luckily, we can do better than juggling a raw pointer and trying to delete it at the right time. The principle of RAII allows objects to take ownership of allocated resources, and automatically release them when their destructor is called as they go out of scope. Containers allow dynamic objects to be maintained within a single scope, and copied if needed; smart pointers allow ownership to be moved or shared between scopes. In this case, a simple container will give us a dynamic array:

void doSomething(){
    std::vector<int> data(100);
} // automatically deallocated

Of course, for a small fixed-size array like this, you might as well just make it automatic:

void doSomething(){
    int data[100];
} // all automatic variables are deallocated
查看更多
一纸荒年 Trace。
7楼-- · 2020-07-11 10:08

This is memory allocated on the heap, and is therefore available outside the function to anything which has its address. The compiler can't be expected to know what you intend to do with heap-allocated memory, and it will not deduce at compile time the need to free the memory by (for example) tracking whether anything has an active reference to the memory. There is also no automatic run-time garbage collection as in Java. In C++ the responsibility is on the programmer to free all memory allocated on the heap.

See also: Why doesn't C++ have a garbage collector?

查看更多
登录 后发表回答