C++中向vector添加person struct元素报错问题排查
问题分析与修复
核心错误原因
你遇到的两种添加元素方法失败的根源都是错误操作了空vector的未分配内存:
- 用
Sample.at(0)赋值:初始状态下Sample是空vector,没有任何元素,at(0)会直接触发越界断言,因为索引0不存在。 - 用全局迭代器
iter赋值:Sample.begin()在空vector时等于Sample.end(),解引用尾后迭代器属于未定义行为,直接导致段错误;而且即使vector后续扩容,之前的迭代器会因内存重新分配而失效。
另外代码里还有其他隐性问题:
inputtedPerson在if/else里被重复定义,覆盖了之前的变量,属于冗余且容易混淆的写法。- 拆分Democrats和Republicans时,用
Democrats.at(demPos)赋值,但这两个vector初始为空,at()同样会触发越界。 Sample.erase(it)后,被erase的迭代器会失效,虽然你用了break,但规范写法应该用erase的返回值更新迭代器。return 0后的代码永远不会执行,属于无效代码。
修复后的完整代码
// DelibDem.cpp : Defines the entry point for the application. // #include "DelibDem.h" #include <stdio.h> #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; struct person{ string Name; string PartyID; string equivalentName; string equivalenceClass; }; int main() { bool continue_ = true; int numD = 0; int numR = 0; vector<person> Sample; // 用户添加人员到vector while (continue_ == true) { string personName; string personPartyID; string answer; person inputtedPerson; cout << "Enter a person's name: "; getline(cin, personName); cout << "Enter the person's party ID (D or R): "; getline(cin, personPartyID); // 直接初始化inputtedPerson,避免重复定义 if (personPartyID == "D") { inputtedPerson = {personName, personPartyID, "", "Republicans"}; } else { inputtedPerson = {personName, personPartyID, "", "Democrats"}; } // 使用push_back添加元素,这是vector添加元素的标准方式 Sample.push_back(inputtedPerson); cout << "Do you wish to add more people? (Y/N) "; cin >> answer; if (answer == "N") { continue_ = false; } cin.ignore(); // 忽略换行符,避免下一次getline读取空内容 } // 统计民主党和共和党人数 for (auto& element : Sample) { if (element.PartyID == "D") { numD++; } else { numR++; } } cout << "民主党人数:" << numD << endl; cout << "共和党人数:" << numR << endl; // 调整人数至相等 if (numD != numR) { cout << "无法建立等价关系,因为 "; if (numD > numR) { int difference = numD - numR; cout << "民主党比共和党多 " << difference << " 人" << endl; while (difference != 0) { string specifiedName; cout << "请选择要移除的民主党成员姓名:" << endl; cin >> specifiedName; // 正确处理erase后的迭代器 bool removed = false; for (auto it = Sample.begin(); it != Sample.end(); ) { if (it->Name == specifiedName && it->PartyID == "D") { it = Sample.erase(it); // erase返回下一个有效迭代器 removed = true; break; } else { ++it; } } if (removed) { difference--; } else { cout << "该人员不是民主党成员,请重新输入。" << endl; } } } else { int difference = numR - numD; cout << "共和党比民主党多 " << difference << " 人" << endl; while (difference != 0) { string specifiedName; cout << "请选择要移除的共和党成员姓名:" << endl; cin >> specifiedName; bool removed = false; for (auto it = Sample.begin(); it != Sample.end(); ) { if (it->Name == specifiedName && it->PartyID == "R") { it = Sample.erase(it); removed = true; break; } else { ++it; } } if (removed) { difference--; } else { cout << "该人员不是共和党成员,请重新输入。" << endl; } } } cout << "现在民主党和共和党人数相等,可以建立等价关系。" << endl; } else { cout << "可以建立等价关系" << endl; } // 打印当前所有成员信息 cout << "\n当前成员信息:" << endl; for (auto& element : Sample) { cout << "姓名:" << element.Name << endl; cout << "党派:" << element.PartyID << endl; cout << "对应成员:" << element.equivalentName << endl; cout << "等价类:" << element.equivalenceClass << endl; cout << endl; } // 拆分民主党和共和党成员,使用push_back而非直接赋值 vector<person> Democrats; vector<person> Republicans; for (auto& element : Sample) { if (element.PartyID == "D") { Democrats.push_back(element); } else { Republicans.push_back(element); } } // 互相分配对应成员 auto iterD = Democrats.begin(); auto iterR = Republicans.begin(); for (; iterD != Democrats.end() && iterR != Republicans.end(); ++iterD, ++iterR) { iterD->equivalentName = iterR->Name; iterR->equivalentName = iterD->Name; } // 将对应关系同步回原Sample for (auto& samplePerson : Sample) { if (samplePerson.PartyID == "D") { auto it = find_if(Democrats.begin(), Democrats.end(), [&samplePerson](const person& p) { return p.Name == samplePerson.Name; }); if (it != Democrats.end()) { samplePerson.equivalentName = it->equivalentName; } } else { auto it = find_if(Republicans.begin(), Republicans.end(), [&samplePerson](const person& p) { return p.Name == samplePerson.Name; }); if (it != Republicans.end()) { samplePerson.equivalentName = it->equivalentName; } } } // 打印更新后的成员信息 cout << "\n更新后的成员信息(含对应关系):" << endl; for (auto& element : Sample) { cout << "姓名:" << element.Name << endl; cout << "党派:" << element.PartyID << endl; cout << "对应成员:" << element.equivalentName << endl; cout << "等价类:" << element.equivalenceClass << endl; cout << endl; } return 0; }
关键修复点说明
- 使用
vector::push_back()添加元素:这是vector添加新元素的标准方法,会自动分配内存并在尾部插入新元素,避免越界问题。 - 移除全局迭代器:迭代器应在需要时创建,且避免在vector扩容后使用旧迭代器。
- 修正
inputtedPerson的定义:避免重复定义变量,直接赋值初始化。 - 正确处理
erase后的迭代器:使用erase返回的迭代器继续遍历,避免迭代器失效。 - 拆分党派vector时用
push_back:不再使用at()访问空vector的不存在索引。 - 修复
return 0后的无效代码:将打印代码移到return之前,并同步对应关系回原Sample。
内容的提问来源于stack exchange,提问作者StanAtkinson
相关产品推荐
相关产品推荐

