C++类无法存储Vector值、数据丢失且VS报错问题求助
问题核心原因
1. 类实例生命周期异常
Train_Time_Entries()函数内定义的Train_Time_Ent myobjs是局部栈变量,函数执行结束后实例会被自动回收销毁,存入的所有vector数据随实例销毁全部丢失,外部无法访问已销毁实例的内容。
2. 匿名结构体滥用
代码定义了一个匿名结构体,同时实例化了十余个全局变量(iop, admus, admpa, AdminUsers...),每个实例独立持有全量结构体成员,属于完全冗余的错误设计,逻辑完全混乱。
3. switch分支缺失break
所有switch的case分支几乎都未添加break,选择某分支执行后会直接串入后续所有分支执行,产生大量不可预期的逻辑错误。
4. 容器越界访问
向sBundle写入数据时使用全局myCo.myContNo作为索引,该值和sDay、sLocations等容器的实际元素数量不匹配,极易触发下标越界访问,是Visual Studio抛出通用错误的直接原因。
修复方案
- 调整类实例生命周期:将
Train_Time_Ent实例从函数局部变量改为全局变量,或作为引用参数传入Train_Time_Entries,保证实例生命周期覆盖所有数据访问场景。 - 清理冗余全局实例:匿名结构体仅保留1个全局实例即可,删除多余的十余个实例,避免逻辑混乱。
- 为所有switch分支补充break,避免逻辑串位。
- 容器访问前先校验索引合法性,优先使用容器自身的
size()方法判断边界,不要依赖全局计数变量避免数值不一致。
关键修改代码示例
// 全局定义Train_Time_Ent实例,生命周期和程序运行周期一致 Train_Time_Ent g_trainEnt; // 匿名结构体仅保留一个全局实例即可 struct { int iOption, iCount = 0; int myContNo = -1; int fDecide = -1; string AdminUser, AdminPass; vector <string> AdminUsers{ "John1966", "Christine55", "BlakeBennett74", "SarahHarding93", "Connor1987" }; vector <string> AdminPasswords{ "KalEL", "HenryDog6", "WesternRailway21", "Railwayssince89", "Budweisersaregood" }; vector <string> sAdmins; bool bAdmin = true, bAddEnt = true, bMenu = true, bMenu1 = true; } g_globalConfig; void Train_Time_Entries() { system("cls"); // 不再定义局部myobjs,直接使用全局g_trainEnt do { cout << " Train Entries(Admin View Only)\n"; for (int i = 0; i < 5; i++) { cin.ignore(); cout << "Please enter a train location: " << flush; string sLocation; getline(cin, sLocation); g_trainEnt.sLocations.push_back(sLocation + "\n"); cout << "Enter a day of the week for times: " << flush; string sDay; cin >> sDay; g_trainEnt.sDay.push_back(sDay + "\n"); // 剩余输入逻辑同理直接操作g_trainEnt的成员 // ... } } while (g_globalConfig.bAddEnt == true); // 用容器自身size判断边界,避免越界 for(int i=0; i<g_trainEnt.sLocations.size(); i++){ if(i < g_trainEnt.sDay.size() && i < g_trainEnt.sArrive.size() && i < g_trainEnt.sDepart.size()){ g_trainEnt.sBundle.push_back(g_trainEnt.sDay[i] + g_trainEnt.sLocations[i] + g_trainEnt.sArrive[i] + g_trainEnt.sDepart[i]); } } // ... } // switch分支补充break示例 switch (g_globalConfig.iOption) { case 1: Train_Time_Entries(); g_globalConfig.bMenu = true; break; case 2: //Reserved_Lists(); g_globalConfig.bMenu = true; break; case 3: //Passenger_Info(); g_globalConfig.bMenu = true; break; case 4: cout << "Returning to Main Menu...\n"; g_globalConfig.bMenu = false; break; }
内容的提问来源于stack exchange,提问作者Calmtb2019
相关产品推荐
相关产品推荐

