C++动态指针数组出现段错误或double free报错该如何解决
问题根源与修复说明
核心报错原因
你遇到的double free和段错误核心是变量作用域覆盖问题:
在case '+'的firstrun==false分支中,你执行delete[] todoptr;后,重新声明了一个局部同名变量 Todo *todoptr = new Todo[arraysize+1];,这个局部变量仅在当前if分支内部生效,出了if块后,外层main函数里的todoptr依然指向已经被释放的内存空间,后续再操作该指针就会触发野指针访问、重复释放等崩溃问题,你删除该位置的Todo类型声明、直接给外层指针赋值的修复方案完全正确。
其他可优化的问题点
MenuChoice函数中使用的变长数组char charray[n+1]是C语言扩展特性,不符合C++标准,直接返回input[0]即可实现相同功能- 动态数组扩容逻辑冗余:你原本的实现先申请tempptr拷贝旧数据、再申请todoptr重复拷贝一次,完全可以省去中间的tempptr,直接申请新的大数组拷贝旧数据即可
- 程序退出时没有调用
delete[] todoptr释放申请的动态内存,存在内存泄漏 - 输入逻辑存在缓冲区残留问题:default分支中用
cin >> quit读取输入后,换行符会残留在输入缓冲区,下次getline会读到空字符串
优化后的完整代码
#include <iostream> #include <sstream> #include <limits> #include <ctime> #include <cstring> using namespace std; class Date { public: Date() { time_t currentdate = time(0); tm* date = localtime(¤tdate); cout << "今日日期: " << 1 + date->tm_mon << "/" << date->tm_mday << "/" << 1900 + date->tm_year << endl << endl; } }; class Todo { public: string todoItem, addDate; int itemID; void setData(string input, int arraysize) { input.erase(0,1); todoItem=input; itemID=arraysize; stringstream buffer; time_t currentdate = time(0); tm* date = localtime(¤tdate); buffer << "添加日期: " << 1 + date->tm_mon << "/" << date->tm_mday << "/" << 1900 + date->tm_year << endl << endl; addDate = buffer.str(); } void getData() { cout <<"读取数据:\n"; cout << itemID << "/" << todoItem << "/" << addDate << endl; } }; void ProgramGreeting(); char MenuChoice(string todoItem); int main() { ProgramGreeting(); bool menuloop=true; bool firstrun=true; string input; int arraysize=1; int arrayindex=arraysize-1; Todo *todoptr = new Todo[arraysize]; do{ getline(cin,input); switch (MenuChoice(input)) { case '+': cout << "添加待办逻辑执行\n"; if (firstrun==false) { arrayindex=arraysize-1; // 直接申请扩容后的新数组,省去冗余的中间拷贝步骤 Todo *newptr = new Todo[arraysize+1]; for (int i = 0; i < arraysize; i++) { newptr[i] = todoptr[i]; } newptr[arrayindex].setData(input, arraysize); delete[] todoptr; // 直接给外层指针赋值,不重复声明局部变量 todoptr = newptr; for (int i = 0; i < arraysize; i++) { todoptr[i].getData(); } } if (firstrun==true) { todoptr->setData(input, arraysize); firstrun=false; } arraysize++; break; case '-': break; case '?': break; default: cout << "输入无效。如果需要退出程序,请输入'Q'"; string quit; cin >> quit; // 清除输入缓冲区残留的换行符,避免后续getline读取空值 cin.ignore(numeric_limits<streamsize>::max(), '\n'); if (quit=="q" or quit=="Q") { menuloop=false; } break; } } while(menuloop==true); // 退出前释放动态申请的内存 delete[] todoptr; return 0; } void ProgramGreeting() { cout << "欢迎使用待办清单工具!\n" "程序作者: John Doe\n"; Date date; cout << endl; } char MenuChoice(string input) { // 移除不符合C++标准的变长数组实现,直接返回首字符 return input.empty() ? '\0' : input[0]; }
内容的提问来源于stack exchange,提问作者user3089304
相关产品推荐
相关产品推荐

