c++ - 为什么当我通过 'delete' 语句为映射释放内存时会发生此错误?

标签 c++

在下面的程序中,我尝试为 std::map 对象释放内存。

#include <map>
#include <iostream>
#include <unistd.h>

int main() {
  // std::map<int, int> *mp = new std::map<int, int>;;
  std::map<int, int> mp;
  for(int i = 0; i < 999999; i++){
    // mp->insert(std::pair<int, int>(i, 999999-i )); 
    mp[i] = 999999-i;
  }

  delete &mp;
  // delete mp;
  pause();
}

程序的两个版本(带有注释或取消注释当前注释并注释相应行)都编译良好,但是当我尝试通过 delete &mp 释放内存时(又名,mp 是 std::map本身,而不是指向 std::map 的指针),它告诉我这个奇怪的错误消息:

test14_1(47555,0x7fff75c6f300) malloc: *** error for object 0x7fff5c601918: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

谁知道为什么会这样?

最佳答案

您的程序中有两个方面。

::map 的分配

通过像您一样声明您的变量,您将在函数 main() 的范围内创建一个 ::map 对象。该映射分配在该函数的堆栈上,并在输入该函数(即函数 scope { .. } )时自动初始化。

释放::map

因为映射是在进入作用域时在堆栈上分配的,所以当函数返回时(即函数作用域关闭)它会自动删除。您无需为此担心。

你做什么...

通过调用 delete 运算符,您正试图从进程 中释放内存。 delete 运算符将指向已分配内存的指针作为参数,通过编写 &mp,您将创建这样一个指针。但是,因为 mp 对象存在于分配它的堆栈中,C++ 运行时会给出错误,即 pointer being freed was not allocated on the heap using the new运营商。

有趣的是,您的程序中已经有了正确的代码,您只是错误地配对了 allocation/free:

// Allocate the memory on the heap, and free it. 
// mp is a pointer to the allocated map.
int main() {
    std::map<int, int> *mp = new std::map<int, int>;
    // do stuff, e.g. mp->insert()
    delete mp;
}
// Allocate the memory on the stack, freed automatically.
// mp is a reference to the allocated map.
int main() {
    std::map<int, int> mp;
    // do stuff, e.g. mp.insert()
    // no need to free mp explicitly!
}

注意

您可能想了解 C/C++ 程序如何组织它们的内存:堆和堆栈内存分配(看看 herehere ),以及指针和内存分配引用之间的区别(看看 herehere)。

PS:您很幸运收到错误消息。在禁用内存安全的优化代码中(例如 gcc 的 memory sanitizer ),您的程序将表现出不确定性并可能崩溃。

关于c++ - 为什么当我通过 'delete' 语句为映射释放内存时会发生此错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30521087/

相关文章:

c++ - 如何在 C++ 中计算 vector 中的字节数?

c++ - 强制注册派生类型

c++ - 我如何强制 Windows 在 SetCursorPos 之后忘记旧的鼠标位置?

c++ - OpenACC - C++ 'new' 运算符问题

c++ - 下面的 C++ shared_ptr 用法会不会有任何泄漏?

c++ - 在 wifstream 析构函数中中止

C++ 模板专门化以提供/添加不同的成员函数

c++ - 带有GTK +/gtkmm网格的分屏

c++ - 为什么在这个例子中调用了复制构造函数?

c++ - OpenCL 在 NVidia 硬件上生成 QNaN