使用Code::Blocks编写C++程序触发SIGSEGV段错误问题求助
解决C++中SIGSEGV段错误(访问未初始化数组导致的内存越界)
先直接说问题根源:你遇到的SIGSEGV (Segmentation fault)错误,本质是Data类里的todo[]数组没有分配内存空间,当你在SeeData()函数里尝试给它赋值时,程序在访问非法内存区域,直接触发了系统的内存保护机制。
错误原因拆解
你的代码里Data类定义了:
string todo[];
这在C里是不合法的(C语言的柔性数组特性不能直接用于C类成员)。这个数组没有被分配任何内存空间,当你执行_myData.todo[i] = todoArr[i];时,相当于往一块不属于你的内存地址写数据,系统自然会抛出段错误。
另外还有两个小问题需要注意:
main()里的_menuInput没初始化,第一次进入循环时可能出现不可预测的行为;SeeData()里外层的for (int i = 0; i < sizeOfData; i++)会重复输出4次相同的个人信息,完全是多余的。
修复方案(用现代C++写法解决)
最稳妥的方式是用std::vector<string>替代固定数组,它能动态管理内存,完美适配todo列表的增删需求。下面是修改后的完整代码:
#include <iostream> #include <stdlib.h> #include <string> #include <vector> // 引入vector头文件 using namespace std; int SeeData(); int ChangeData(); void AddTodo(); // 调整返回类型,原逻辑不需要返回string class Data { public: string name; string surname; string age; string salary; vector<string> todo; // 用vector替代未初始化的数组 }; string dataArr[] = {"Bernardo", "Piedade", "19", "540.50"}; vector<string> todoArr = {"Create new functions"}; // 同步改成vector更方便 int main() { int _menuInput = 0; // 初始化变量,避免未定义行为 while (_menuInput != 0) { cout << "[1] - See data\n[2] - Change data\n[3] - Add TODO\n[0] - " << "Exit\n\n>>"; cin >> _menuInput; if (_menuInput == 1) { SeeData(); } else if (_menuInput == 2) { ChangeData(); } else if (_menuInput == 3) { AddTodo(); } else if (_menuInput == 0) { system("exit"); } else { cout << "Option not available\n"; system("cls"); } } return 0; } int sizeOfData = sizeof(dataArr) / sizeof(*dataArr); int SeeData() { Data _myData; _myData.name = dataArr[0]; _myData.surname = dataArr[1]; _myData.age = dataArr[2]; _myData.salary = dataArr[3]; // 直接复制todoArr的内容到_myData.todo,vector自动处理内存 _myData.todo = todoArr; // 输出个人信息,去掉多余的循环 cout << "Name: " << _myData.name << "\nSurname: " << _myData.surname << "\nAge: " << _myData.age << "\nSalary: " << _myData.salary << "\n\n"; cout << "Todo List: \n"; // 用范围for循环遍历,代码更简洁 for (const auto& item : _myData.todo) { cout << "\t- " << item << "\n"; } return 0; // 函数需要返回int类型的值 } int ChangeData() { // 这里可以补充修改数据的逻辑,比如修改dataArr的内容 return 0; } void AddTodo() { // 补充添加todo的逻辑示例 string newTodo; cout << "Enter new todo item: "; cin.ignore(); // 忽略之前输入残留的换行符 getline(cin, newTodo); todoArr.push_back(newTodo); cout << "Todo added successfully!\n"; }
关键修改说明
- 替换未初始化数组为vector:
vector<string>会自动分配和管理内存,你可以用push_back()添加元素,直接赋值就能复制其他vector的内容,彻底避免手动管理内存的风险。 - 初始化循环变量:给
_menuInput初始值0,避免第一次循环时的未定义行为。 - 优化输出逻辑:去掉重复输出的循环,用范围for循环遍历todo列表,代码更简洁易读。
- 调整函数返回值:
AddTodo原逻辑不需要返回string,改成void更合理,同时补充了简单的添加todo功能。
修改后再运行程序,选择选项1就不会再触发段错误了,代码也更符合现代C++的编程规范。
内容的提问来源于stack exchange,提问作者BernardoPiedade
相关产品推荐
相关产品推荐

