使用new创建的指针调用std::move后是否需要手动delete?
关于std::move与new/delete的内存管理问题解答
1. 必须手动delete由new创建的指针
new string会在堆上分配两块独立内存:
- 一块是
string对象本身的内存(存着缓冲区指针、大小、容量等管理数据) - 另一块是
string用来存字符的缓冲区内存
std::move(*a)只是把*a内部的字符缓冲区所有权转移给了b,但*a这个对象本身占用的堆内存并没有被处理——这块内存是通过new分配的,只能用delete来回收,不手动调用的话会造成内存泄漏。
2. b的析构函数不会释放a指向的内存
b的析构函数只会负责释放它自己拥有的字符缓冲区(也就是从*a转移过来的那块),但a指向的是string对象本身的堆内存,这块内存和b没有关联,b的析构根本不会碰它。
3. 手动调用delete a后,b的析构完全正常
std::move执行后,*a会变成一个空的有效string对象(内部缓冲区指针被置空,或者处于安全的未使用状态)。此时调用delete a会做两件事:
- 调用
*a的析构函数:因为*a是空的,析构它不会释放任何缓冲区 - 回收
*a对象本身的堆内存
而b的析构函数会正常释放它从*a转移过来的字符缓冲区,两者互不干扰,不会出现双重释放或者野指针问题。
修正后的代码示例:
#include <algorithm> #include <string> using namespace std; int main() { string* a = new string("Hello World"); string b = move(*a); // 此时*a的内部字符缓冲区已经转移给b,*a变为空string delete a; // 必须调用,回收new分配的string对象内存 // main结束时b自动析构,释放它持有的字符缓冲区 }
内容的提问来源于stack exchange,提问作者Altman Jeffry
相关产品推荐
相关产品推荐

