包含指针不工作的类的向量

问题描述

我有这个 C++ 代码

#include <vector>
using namespace std;

struct Test {
    int* member = 0;

    test() {}
    Test(const Test& o) { member = new int(*o.member); }
    ~test() { delete member; }
};

int main()
{
    vector<Test> vecTest = {
        test(),test(),test()
    };

    vecTest.erase(vecTest.begin());
}

此程序正确构建,但它崩溃并显示退出代码 -1073741819。我做错了什么?

解决方法

-1073741819 是十六进制 0xC0000005。这是未捕获的访问冲突异常的退出代码。这意味着您的代码正在访问无效内存。

您的向量是用 Test 对象初始化的,这些对象持有空指针。当您擦除第一个对象时,剩余的对象必须在向量中向下移动。但是,由于您的类没有实现移动语义,因此必须复制对象。当 o.membernullptr 时,您的复制构造函数不处理这种情况。而且您的类根本没有实现复制赋值运算符,因此违反了 Rule of 3/5/0,这会导致内存泄漏和多个对象最终持有相同的指针,从而导致内存的双重删除。

试试这个:

class Test {
    int* member;
public:
    Test() { member = new int(); }
    Test(const Test& o) { member = new int(*(o.member)); }
    ~Test() { delete member; }

    Test& operator=(const Test& rhs) {
        if (&rhs != this) {
            *member = *(rhs.member);
        }
        return *this;
    }
};

或者,添加移动语义:

class Test {
    int* member;
public:
    Test() { member = new int(); }
    Test(const Test& o) { member = new int(*(o.member)); }
    Test(Test&& o) { member = o.member; o.member = nullptr; }
    ~Test() { delete member; }

    Test& operator=(Test rhs) {
        std::swap(member,rhs.member);
        return *this;
    }
};

话虽如此,请考虑使用 std::unique_ptr 来帮助进行内存管理:

class Test {
    std::unique_ptr<int> member;
public:
    Test() { member = std::make_unique<int>(); }
    Test(const Test& o) { member = std::make_unique<int>(*(o.member)); }
    Test(Test&& o) { member = std::move(o.member); }

    Test& operator=(Test rhs) {
        std::swap(member,rhs.member);
        return *this;
    }
};