You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态替换动态分配数组内容失效,为何出现错误输出?

动态数组复制后vector元素异常的原因

问题代码

struct A {
    int *p;
};

int main()
{
    vector<A> v;
    A test;
    test.p = new int[5];

    //fill the array
    for (int i = 0; i < 5; i++)
        test.p[i] = i;

    v.push_back(test);

    A test2;
    test2.p = new int[10];

    //fill the array
    for (int i = 0; i < 10; i++)
        test2.p[i] = i;

    delete[] test.p;
    //reallocate test to test2
    test.p = new int[10];
    //copy test2 to test
    for (int i = 0; i < 10; i++)
        test.p[i] = test2.p[i];
    
    //delete test2
    delete[] test2.p;

    //print the array
    for (int i = 0; i < 10; i++)
        cout << v[0].p[i] << endl;

    return 0;
}

异常输出

0
0
-997294064
32767
4
0
33
0
-997220688
32767

问题根源

核心问题是浅拷贝导致的野指针访问:

  • 当执行v.push_back(test);时,vector会复制一份test对象存入容器。但struct A的默认拷贝构造函数只会复制指针p的数值,不会复制指针指向的内存——也就是说,容器里的A对象和原test对象的p指针指向同一块int[5]的内存。
  • 后续调用delete[] test.p;直接释放了这块内存,此时v[0].p就变成了野指针,指向已经被系统回收的内存空间。
  • 最后访问v[0].p[i]属于访问已释放的内存,这是C++中的未定义行为,因此输出出现随机乱码。

你后续给test的p重新分配新内存的操作,和容器里的v[0].p没有任何关联,容器内的指针依然指向已释放的旧内存。

解决办法

1. 实现深拷贝

给struct A定义自定义的拷贝构造函数、赋值运算符和析构函数,在拷贝时复制指针指向的内存,而非仅复制指针本身:

struct A {
    int size;
    int *p;

    // 构造函数
    A(int s = 0) : size(s), p(s ? new int[s] : nullptr) {}

    // 拷贝构造函数
    A(const A& other) : size(other.size), p(new int[other.size]) {
        for (int i = 0; i < size; i++) {
            p[i] = other.p[i];
        }
    }

    // 赋值运算符重载
    A& operator=(const A& other) {
        if (this != &other) {
            delete[] p;
            size = other.size;
            p = new int[size];
            for (int i = 0; i < size; i++) {
                p[i] = other.p[i];
            }
        }
        return *this;
    }

    // 析构函数
    ~A() {
        delete[] p;
    }
};

2. 避免手动管理内存

直接用std::vector<int>替代int*,让标准库自动处理内存和拷贝逻辑,代码更简洁安全:

struct A {
    vector<int> p;
};

int main()
{
    vector<A> v;
    A test;
    test.p.resize(5);
    for (int i = 0; i < 5; i++)
        test.p[i] = i;

    v.push_back(test);

    A test2;
    test2.p.resize(10);
    for (int i = 0; i < 10; i++)
        test2.p[i] = i;

    test.p = test2.p; // vector自动完成深拷贝

    for (int i = 0; i < 5; i++)
        cout << v[0].p[i] << endl;

    return 0;
}

内容的提问来源于stack exchange,提问作者Carlos López Martínez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 03:35:25