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

C++遍历自定义List类存储的Chunk对象时程序崩溃该如何解决

崩溃原因
  • 自定义List类的At方法设计错误:当前At按值返回T而非引用,每次调用chunks.At(i)都会生成一个Chunk临时副本。而Chunk包含List<Block>类型的成员,List没有自定义拷贝构造函数,默认生成的拷贝构造只会做浅拷贝,导致临时副本的blocks和原Chunk的blocks共享同一块堆内存,访问时极易出现未定义行为。这也解释了你直接声明单个Chunk对象可以正常运行的原因:这种场景下没有发生Chunk的拷贝,不存在浅拷贝带来的内存问题。
  • List类完全没有实现拷贝控制(拷贝构造、拷贝赋值、析构函数),违反C++的三五法则,当List对象被拷贝、销毁时会出现野指针、重复释放等内存问题。
  • 额外的风险点:At方法在索引越界时没有任何返回值,属于典型的未定义行为;如果内存被破坏导致blocks.size被读取为一个极大的错误值,会让内层循环次数暴增,占满CPU甚至触发系统内存保护,最终导致整机卡死。
解决方法

有两种可行方案:

方案1:修复自定义List类

  • 修改At方法返回引用,减少不必要拷贝同时避免浅拷贝问题,同时补充越界处理:
T& At(int index) {
    if (index < 0 || index >= size) {
        throw std::out_of_range("List index out of range");
    }
    return ptr[index];
}
// 补充const版本用于const对象访问
const T& At(int index) const {
    if (index < 0 || index >= size) {
        throw std::out_of_range("List index out of range");
    }
    return ptr[index];
}
  • 补充拷贝控制函数,避免浅拷贝:
// 析构函数
~List() {
    delete[] ptr;
}
// 拷贝构造
List(const List<T>& other) {
    size = other.size;
    ptr = new T[65536];
    for (int i = 0; i < size; i++) {
        ptr[i] = other.ptr[i];
    }
}
// 拷贝赋值运算符
List<T>& operator=(const List<T>& other) {
    if (this != &other) {
        delete[] ptr;
        size = other.size;
        ptr = new T[65536];
        for (int i = 0; i < size; i++) {
            ptr[i] = other.ptr[i];
        }
    }
    return *this;
}
  • 修改Add方法参数为常量引用,减少不必要的临时对象拷贝:
void Add(const T& a) {
    ptr[size] = a;
    size++;
}

方案2:直接替换为std::vector(更推荐)

自定义容器很容易出现内存管理错误,直接用标准库的std::vector可以规避所有以上问题,替换逻辑如下:

  1. 把所有List<T>替换为std::vector<T>
  2. 把Add方法调用替换为push_back/emplace_back
  3. 把At(index)调用替换为operator[](index)(无越界检查,性能更高)或者at(index)(有越界检查,调试更方便)

替换后你的主循环代码可以改为:

std::vector<Chunk> chunks;
chunks.emplace_back(4, glm::vec3(0.0f)); // emplace_back直接构造,避免额外拷贝

while (!glfwWindowShouldClose(display.window)) {
    renderer.Prepare();
    for (int i = 0; i < chunks.size(); i++) {
        for (int j = 0; j < chunks[i].blocks.size(); j++) {
            renderer.Render(chunks[i].blocks[j]);
        }
    }
    renderer.Clear();
}

内容的提问来源于stack exchange,提问作者user15918026

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:04