为什么你必须为存储在堆中的函数的局部变量调用delete? [英] Why do you have to call delete for local variables of a function that are stored in the heap?

查看:305
本文介绍了为什么你必须为存储在堆中的函数的局部变量调用delete?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设你有以下函数:

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

为什么会产生内存泄漏?因为我不能在函数外访问这个变量,为什么编译器在每次调用这个函数时都调用delete?

解决方案<为什么会产生内存泄漏?


因为你负责删除你创建的任何东西 new


为什么编译器不调用delete


通常,编译器无法判断你是否还有一个指针分配的对象。例如:

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

doSomethingElse 在函数调用期间使用指针(在这种情况下我们仍然要删除数组在这里)?它是否存储指针的副本以供稍后使用(在这种情况下,我们不想删除它)?编译器没有办法知道;它是由你来告诉它。而不是做一个复杂的,容易出错的规则(像你必须删除它,除非你能知道编译器必须知道没有其他引用它),规则保持简单:你必须删除它。 / p>

幸运的是,我们可以做得比玩弄一个原始指针,并试图在正确的时间删除它。 RAII 的原则允许对象获取已分配资源的所有权,并在对象的析构函数超出范围时自动释放它们。容器允许动态对象在单个范围内维护,并在需要时复制;智能指针允许所有权在范围之间移动或共享。在这种情况下,一个简单的容器将给我们一个动态数组:

  void doSomething(){
std :: vector< int>数据(100);
} //自动释放

当然,对于像这样的小型固定大小的数组,你可能只是让它自动:

  void doSomething(){
int data [100]
} //所有自动变量被释放


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?

解决方案

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

这篇关于为什么你必须为存储在堆中的函数的局部变量调用delete?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆