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

游戏开发中动态数组执行delete []触发Segmentation Fault问题求助

解决动态数组存储Player时的Segmentation Fault问题

你遇到的段错误根源是错误地使用memcpy来拷贝包含非POD类型(比如std::string)的对象数组。咱们一步步拆解问题,再给出修复方案:

问题核心原因

memcpy是字节级的浅拷贝工具,它只适合处理POD(Plain Old Data)类型——也就是没有自定义构造/析构函数、内部成员都是基础数据类型的对象。而你的Player类包含std::string,这个类型内部管理着堆内存,浅拷贝会导致致命问题:

  1. 第一次添加玩家时,PlayerList是NULL,memcpy没执行操作,暂时没问题;
  2. 第二次添加玩家时,memcpy把旧数组里的Player字节拷贝到新数组,此时新、旧数组里的Player对象的PlayerName(std::string)指向同一块堆内存;
  3. 调用delete [] PlayerList释放旧数组时,旧数组里的Player析构函数会触发std::string的析构,释放那块堆内存;
  4. 第三次添加玩家时,新数组里的Player的PlayerName已经是野指针了,再次执行delete []时,程序尝试释放已经被释放过的内存,直接触发段错误。

修复方案:用逐对象拷贝替代memcpy

我们需要调用Player的赋值运算符来完成深拷贝,这样std::string会正确复制内部的堆内存,避免野指针和双重释放。修改resizePlayerList函数如下:

void Game::resizePlayerList() {
    if(NewPlayer.getPlayerName() != "") { // 原条件"No Name"和默认构造的""不匹配,这里统一成空字符串判断
        int newSize = NPlayers + 1;
        Player* newArr = new Player[newSize];
        
        // 逐对象拷贝,触发Player的赋值运算符,std::string会完成深拷贝
        for(int i = 0; i < NPlayers; ++i) {
            newArr[i] = PlayerList[i];
        }
        
        NPlayers = newSize;
        delete [] PlayerList;
        PlayerList = newArr;
        PlayerList[NPlayers-1] = NewPlayer;
    }
}

额外优化建议

  1. 修复Game类的内存泄漏:当前Game的析构函数是空的,会导致PlayerList的内存永远无法释放,补充析构逻辑:
Game::~Game() {
    delete [] PlayerList;
};
  1. 替换手动动态数组为std::vector:你已经注释掉了std::vector<Player> PlayerList2;,其实std::vector会自动管理内存扩容和释放,完全不需要手动写resize逻辑,代码会更简洁安全:
// 把Game类里的Player* PlayerList;改成:
std::vector<Player> PlayerList;

// 然后resizePlayerList可以简化成:
void Game::resizePlayerList() {
    if(NewPlayer.getPlayerName() != "") {
        PlayerList.push_back(NewPlayer);
        // NPlayers也可以去掉,直接用PlayerList.size()获取玩家数量
    }
}
  1. 避免头文件里的using namespace std;:头文件里使用这个会污染全局命名空间,建议头文件里用std::string、std::cout这样的前缀,只在实现文件里按需使用using namespace std;。

修改后运行你的主函数,三次添加玩家都会正常执行,PrintList也会正确输出所有玩家信息,不会再触发段错误。

内容的提问来源于stack exchange,提问作者Pedro R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:52:35