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

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(&currentdate);
        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(&currentdate);
        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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:36:03