为什么当我通过语句释放 Map 的内存时会发生此错误'delete'?
why this error happens when I release memory for map through 'delete' statement?
在下面的程序中,我尝试为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
对象。映射在该函数的堆栈上分配,并在该函数(即函数作用域{ .. }
)进入时自动初始化。
释放::map
因为map是在进入作用域时在堆栈上分配的,所以当函数返回时(即函数作用域关闭),它会被自动删除。你不必担心这个。
通过调用delete
操作符,您试图从进程堆中释放内存。delete
操作符将指向已分配内存的指针作为参数,通过写入&mp
,您正在创建这样一个指针。但是,由于mp
对象位于分配它的堆栈上,因此c++运行时给您的错误是pointer being freed was not allocated
在使用new
操作符的堆上。
// 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++程序如何组织它们的内存:堆和堆栈内存分配(看看这里或这里),以及指针和内存分配的引用之间的区别(看看这里或这里)。
PS: 你很幸运看到错误信息。在禁用内存安全的优化代码中(例如gcc的内存消毒器),程序的行为将不确定,可能会崩溃。
您不需要删除std::map
,因为您没有使用new
操作符分配内存。所有标准容器(如std::map
)都能够自己管理它们的内存。他们内部使用allocator
进行内存管理。
使用
std::map<int, int> mp;
delete ∓
类似于:
int i;
delete &i;
是错误的
只有在使用new
分配对象时,才需要使用delete
来释放内存。
在堆栈上创建的对象将自动删除。如果类的析构函数做了正确的事情,客户机代码就没有更多的事情要做了。在std::map
的情况下,析构函数将执行必要的解分配。你的函数不需要做任何事情
这是基本的RAII。
任何堆栈局部对象,包括int/float等类型的简单变量,或者在你的例子中是容器,在作用域结束时被销毁。
对于显式销毁,
{
vector<int> v1;
map<int,int> m1;
delete &m1;
} // implicit destruction of v1 and m1!
使用显式delete语句,结果代码将最终释放已经释放的内存。
- 重载 new 和 delete 会导致 valgrind 错误
- 为什么在c++中使用Delete[]会出现跟踪/断点错误
- 在析构函数中调用"delete"运算符时"compiler is out of heap space"编译器错误
- 为什么 delete[] 会导致堆损坏错误
- 在 Visual Studio 2012 中使用 "= delete" 时出现编译器错误
- `delete []`on`int*````new'''给出了malloc错误
- 在使用new和delete的情况下交叉编译错误
- 在回溯中使用“delete”解除分配时,出现“free()”错误
- 如何从 free() 或 delete() 中捕获或处理段错误
- delete[]调用析构函数时出现内存错误
- Delete导致基类中的虚拟析构函数出现内存错误
- 对指向对象的指针调用delete[]时发生BLOCK_TYPE_VALID错误
- 为什么在非指针堆栈分配变量上调用 delete 时C++不给出编译器错误?
- c++ Delete[]在VS 2013中给出错误
- 当构造函数抛出异常时,Delete操作符出现分段错误
- QT 5.2.1编译错误;在'delete'之前期望的非限定id
- 调用带有delete的析构函数时出现错误
- 运行时错误与"delete[]"
- 赋值运算符中的 free() / delete / delete[] / realloc() 错误无效
- 为什么当我通过语句释放 Map 的内存时会发生此错误'delete'?