自制C++ Vector类pushBack函数内存泄漏与崩溃问题求助
我来帮你拆解下当前遇到的问题,崩溃和内存泄漏的根源其实都和内存管理的细节有关,咱们一步步解决:
1. 崩溃的核心原因:未初始化的野指针
看你的Vector默认构造函数:
Vector(): siz(0){}
这里的elem指针没有被初始化为nullptr,它会变成一个野指针(指向内存中随机的无效地址)。当你第一次调用pushBack执行delete[] elem;时,程序会尝试释放一块根本不属于你的内存,直接触发崩溃。
先修正构造函数,把elem初始化为空指针:
Vector(): siz(0), elem(nullptr){}
C++标准规定delete[] nullptr是安全的,不会产生任何问题,这下后续的内存释放就有了保障。
2. 完善pushBack的内存管理逻辑
现在elem有了正确的初始值,你可以放心加上delete[] elem;来避免内存泄漏了,修正后的pushBack代码如下:
void Vector::pushBack(std::string const& s){ std::string* temp = new std::string[siz + 1]; for(int i = 0; i < siz; i++) temp[i] = elem[i]; temp[siz] = s; delete[] elem; // 现在安全执行,elem要么是nullptr要么是之前分配的有效内存 this->elem = temp; this->siz += 1; }
3. 隐藏的坑:拷贝构造与赋值运算符的浅拷贝问题
你已经声明了赋值运算符,但如果没有正确实现,会导致浅拷贝问题:两个Vector对象共享同一个elem指针。当其中一个对象销毁时,delete[] elem会释放内存,另一个对象再访问elem就会触发悬空指针错误,同样会崩溃。
首先要给Vector类补充拷贝构造函数和析构函数的声明(添加到vector.h的public区域):
Vector(const Vector& other); // 拷贝构造函数 ~Vector(); // 析构函数
然后实现拷贝构造、赋值运算符和析构函数:
// 析构函数:负责释放elem指向的内存 Vector::~Vector(){ delete[] elem; } // 拷贝构造函数:深拷贝,确保每个对象有独立的内存空间 Vector::Vector(const Vector& other) : siz(other.siz), elem(new std::string[other.siz]) { for(int i = 0; i < siz; ++i){ elem[i] = other.elem[i]; } } // 赋值运算符:用"拷贝并交换"惯用法,简洁又安全 Vector& Vector::operator=(Vector other) { // 传值参数会触发拷贝构造 std::swap(siz, other.siz); std::swap(elem, other.elem); return *this; }
"拷贝并交换"的好处是自动处理了自我赋值的情况,而且代码简洁不容易出错。
4. 补充:析构函数的必要性
之前你的类没有析构函数,当Vector对象生命周期结束时,elem指向的内存不会被释放,必然导致内存泄漏。上面添加的析构函数会在对象销毁时自动释放内存,彻底解决这个问题。
现在你的Vector类就具备了完整且安全的内存管理能力,pushBack既不会崩溃,也不会产生内存泄漏,同时拷贝和赋值操作也能安全执行了。
内容的提问来源于stack exchange,提问作者Ádám Szűcs

