在下面的程序中,我尝试为 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 ∓
// 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++ 程序如何组织它们的内存:堆和堆栈内存分配(看看 here 或 here ),以及指针和内存分配引用之间的区别(看看 here或 here)。
PS:您很幸运收到错误消息。在禁用内存安全的优化代码中(例如 gcc 的 memory sanitizer ),您的程序将表现出不确定性并可能崩溃。
关于c++ - 为什么当我通过 'delete' 语句为映射释放内存时会发生此错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30521087/