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

C++ vector元素每次输入后全部被覆盖的问题如何修复?

问题修复方案

核心问题原因

  • 内存分配错误:你给name/highscore/password三个指针仅分配了1字节内存,连字符串末尾的结束符\0都无法存储,读入任意长度大于1的字符串都会触发内存越界,属于未定义行为。
  • 指针重复复用:所有指针和player对象都是在循环外仅初始化一次,每次读入的新内容都会覆盖同一块内存空间,vector中存储的都是指向同一块内存的指针,自然所有元素都会同步变成最新输入的值。
  • 不必要的堆分配:vector <char*>* names这种用指针存储vector的写法完全没有必要,直接在栈上声明vector即可,反而会增加内存泄漏风险。
  • 输入判断逻辑错误:while(input.good())的判断会导致最后一行内容重复读入,应该直接将输入操作放到while循环的判断条件中。

推荐修复方案(C++标准写法,无手动内存管理风险)

优先将player类的char*类型成员替换为std::string,无需手动管理内存,从根源避免越界、泄漏、覆盖问题:

// 修改player类定义
class player {
public:
    std::string name;
    std::string highscore;
    std::string password;
    player(std::string n, std::string h, std::string p) 
        : name(std::move(n)), highscore(std::move(h)), password(std::move(p)) {}
    // 对应的>>运算符重载也修改为直接读入string成员即可
    friend std::istream& operator>>(std::istream& in, player& p) {
        // 按你的csv分隔逻辑读入三个字段到p.name、p.highscore、p.password
        return in;
    }
};

// 业务代码修改为
std::vector<player> players;
std::vector<std::string> names;
std::vector<std::string> passwords;
std::vector<int> scores;
std::ifstream input("user.csv");        

std::cout << "Welcome to Champion Yahtzee\n";
std::cout << "Player Name            Highest Score\n";
std::cout << "-----------            -------------\n";
player tmp;
while (input >> tmp) { // 读入成功才执行后续逻辑
    players.push_back(tmp);
    names.push_back(tmp.name);
    scores.push_back(std::stoi(tmp.highscore));
    passwords.push_back(tmp.password);
}

保留char*写法的修复方案(不推荐,需自行管理内存避免泄漏)

如果必须使用char*,需要把内存分配逻辑放到循环内部,每次读入前都申请新的内存空间:

std::vector<player*> players;
std::vector<char*> names;
std::vector<char*> passwords;
std::vector<int> scores;
std::ifstream input("user.csv");        

std::cout << "Welcome to Champion Yahtzee\n";
std::cout << "Player Name            Highest Score\n";
std::cout << "-----------            -------------\n";
const int BUF_SIZE = 128; // 根据实际字段最大长度调整缓冲区大小
while (true) {
    // 每次循环申请新的内存
    char* name = (char*)malloc(BUF_SIZE * sizeof(char));
    char* highscore = (char*)malloc(BUF_SIZE * sizeof(char));
    char* password = (char*)malloc(BUF_SIZE * sizeof(char));
    player* c = new player(name, highscore, password);
    if (!(input >> *c)) {
        // 读入失败释放内存后退出循环
        free(name);
        free(highscore);
        free(password);
        delete c;
        break;
    }
    players.emplace_back(c);
    names.push_back(name);
    scores.push_back(atoi(highscore));
    passwords.push_back(password);
}
// 注意:程序退出前需要遍历所有vector,逐个free char*、delete player对象,否则会出现内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:54:04