c++ - 为什么必须为存储在堆中的函数的局部变量调用 delete?

标签 c++ memory memory-leaks

假设你有以下函数:

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

为什么会产生内存泄漏?既然不能在函数外访问这个变量,为什么每次调用这个函数结束时编译器都不会自己调用delete呢?

最佳答案

Why will this produce a memory leak?

因为您有责任删除您使用 new 创建的任何内容。

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

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

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

doSomethingElse 是否只是在函数调用期间使用指针(在这种情况下,我们仍然想在这里删除数组)?它是否存储了指针的拷贝以供以后使用(在这种情况下,我们还不想删除它)?编译器无从知晓;由你来告诉它。与其制定一个复杂的、容易出错的规则(例如“除非你能弄清楚编译器必须知道没有其他对它的引用,否则你必须删除它”),规则保持简单:你必须删除它。

幸运的是,我们可以做得比处理原始指针并尝试在正确的时间删除它更好。 RAII的原理|允许对象获得分配资源的所有权,并在它们超出范围时调用其析构函数时自动释放它们。容器允许在单个范围内维护动态对象,并在需要时进行复制;智能指针允许在作用域之间移动或共享所有权。在这种情况下,一个简单的容器会给我们一个动态数组:

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

当然,对于像这样一个固定大小的小数组,你不妨让它自动化:

void doSomething(){
    int data[100];
} // all automatic variables are deallocated

关于c++ - 为什么必须为存储在堆中的函数的局部变量调用 delete?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28833300/

相关文章:

c++ - 在头文件或实现文件中定义常量的优点

winapi - 如何确定最佳线程堆栈大小?

c++ - 池类抛出错误

c++ - 在 Qt 中使用 libarchive - 构建错误

c++ - 表达式中的 bool 操作

c++ - 堆栈/堆变量的变量/引用名称或类型存储在内存中的什么位置?

c - 为什么常量存储在 C 内存映射的文本段中?

c - Valgrind 在检查内存泄漏时可能丢失消息 - C

android - 由于 Firebase 中 ValueEventListener 的匿名实现而导致内存泄漏

python - 使用 Dowser 在 Python 中跟踪内存泄漏