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

删除struct成员后如何保留std::vector中存储的struct类型元素的值

问题根因

std::vector::push_back对未自定义拷贝逻辑的结构体执行默认浅拷贝,只会复制结构体内部的指针地址,不会复制指针指向的堆内存内容。你声明的变量a和存入vector的A实例的str指针指向同一块内存,释放a.str时这块内存会被回收,vector内的指针就变成了野指针,自然读取不到原有内容。

解决方法

要实现删除a.str后vector内的值仍然保留,核心是让vector内的A实例拥有独立的内存副本,和原变量a的指针不共用内存,有两种常用实现方案:


方案1:给结构体自定义深拷贝逻辑

符合C++三/五法则要求,手动实现拷贝构造、赋值运算符重载、析构函数,完成堆内存的独立复制与释放,示例代码如下:

#include <vector>
#include <string>
#include <cstring>

struct A
{
    char* str;
    char* str1;
    // 自定义拷贝构造,push_back时自动调用,为新实例申请独立内存
    A(const A& other) {
        str = new char[strlen(other.str) + 1];
        strcpy(str, other.str);
        str1 = new char[strlen(other.str1) + 1];
        strcpy(str1, other.str1);
    }
    // 赋值运算符重载,避免赋值时出现浅拷贝
    A& operator=(const A& other) {
        if (this == &other) return *this;
        // 先释放原有内存
        delete[] str;
        delete[] str1;
        // 申请新内存复制内容
        str = new char[strlen(other.str) + 1];
        strcpy(str, other.str);
        str1 = new char[strlen(other.str1) + 1];
        strcpy(str1, other.str1);
        return *this;
    }
    // 析构函数自动释放内存,避免泄漏
    ~A() {
        delete[] str;
        delete[] str1;
    }
};

int main(){
    std::vector<A> vect;
    std::string b = "Data structures using c and c++";
    A a;
    // 修正原代码内存申请错误:按字符串实际长度申请空间,避免越界
    a.str = new char[b.size() + 1];
    a.str1 = new char[16];
    strcpy(a.str, b.c_str());
    strcpy(a.str1, "test content");
    
    vect.push_back(a); // 此时调用自定义拷贝构造,vector内元素有独立内存

    // 释放a的内存,不会影响vector内的内容
    delete[] a.str;
    delete[] a.str1;
    a.str = a.str1 = nullptr;

    // vector内的元素内容可正常访问
    return 0;
}

注意:new[]申请的数组内存必须用delete[]释放,用delete属于未定义行为。


方案2:用std::string替换裸指针(更推荐)

std::string内部已经实现了安全的深拷贝逻辑,不需要手动管理内存,代码更简洁也更不容易出错,示例如下:

#include <vector>
#include <string>

struct A
{
    std::string str;
    std::string str1;
};

int main(){
    std::vector<A> vect;
    std::string b = "Data structures using c and c++";
    A a;
    a.str = b;
    a.str1 = "test content";
    
    vect.push_back(a); // string自动完成深拷贝,vector内有独立副本

    a.str.clear(); // 清空a的str,或者直接销毁a,都不会影响vector内的内容
    return 0;
}
额外注意事项
  • 原代码中new char[10*sizeof(char*)]写法错误:sizeof(char*)是指针本身的大小(64位系统下为8字节),存储字符串只需按字符数申请内存即可,该写法会导致内存申请冗余甚至后续字符串越界。
  • 手动管理裸指针内存极易出现泄漏、野指针、越界问题,非必要场景优先用STL容器代替裸指针。

内容的提问来源于stack exchange,提问作者somu_mtech

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:45:06