动态对象指针数组插入新元素时内存分配错误排查求助
问题分析与修复方案
咱们直接切入问题核心,一步步排查并修复你的Array类内存错误问题:
1. 最致命的问题:缺失默认构造函数
你的BinaryHeap构造函数里调用了new Array(),也就是默认构造函数,但你的Array类并没有显式定义这个构造——编译器自动生成的默认构造不会初始化_headPtr和arraySize这两个成员变量。这直接导致:
arraySize变成随机的垃圾值,第一次调用pushBack时,if (arraySize == 0)的条件几乎不可能成立,直接进入else分支- 用垃圾值的
arraySize +1去分配内存,要么分配超大数组导致内存不足,要么因为负数触发内存分配失败,直接崩溃在new Edge*[arraySize +1]这一行
2. 次要问题:pushBack的逻辑冗余+误删外部对象
你原来的pushBack里写了delete _headPtr[i],这是错误的——这些Edge*是外部代码(比如BinaryHeap里的new Edge(...))创建的,Array只是存储指针的容器,不应该负责销毁这些Edge对象,否则外部再访问这些对象就会触发_free_dbg这类内存错误,你注释掉这部分是正确的。
另外,pushBack的if-else逻辑可以简化,不用分情况处理初始状态。
修复后的完整代码实现
第一步:补充Array类的默认构造与必要方法
#include "Edge.h" class Array { private: Edge** _headPtr; int arraySize; public: // 默认构造:初始化空数组 Array(); // 带初始容量的构造 Array(int initialSize); // 析构函数:释放指针数组(注意不释放Edge对象) ~Array(); // 禁用拷贝构造与赋值(避免浅拷贝导致的重复释放) Array(const Array&) = delete; Array& operator=(const Array&) = delete; void pushBack(Edge* element); // 你需要的getSize方法 int getSize() const { return arraySize; } // 其他函数... };
第二步:实现构造与析构函数
// 默认构造:初始化空状态 Array::Array() : _headPtr(nullptr), arraySize(0) {} // 带初始容量的构造 Array::Array(int initialSize) : arraySize(0), _headPtr(nullptr) { if (initialSize > 0) { arraySize = initialSize; _headPtr = new Edge*[initialSize]; // 初始化数组内的指针为nullptr,避免野指针 for (int i = 0; i < initialSize; ++i) { _headPtr[i] = nullptr; } } // 如果initialSize<=0,保持空状态 } // 析构函数:只释放指针数组本身,不释放Edge对象 Array::~Array() { delete[] _headPtr; _headPtr = nullptr; arraySize = 0; }
第三步:简化并修复pushBack方法
void Array::pushBack(Edge* element) { // 分配新的指针数组,容量+1 Edge** tempPtr = new Edge*[arraySize + 1]; // 如果原数组有元素,拷贝过去 if (arraySize > 0) { memcpy(tempPtr, _headPtr, arraySize * sizeof(Edge*)); // 释放原指针数组 delete[] _headPtr; } // 添加新元素 tempPtr[arraySize] = element; // 更新成员变量 _headPtr = tempPtr; arraySize++; }
修复逻辑说明
- 默认构造显式初始化
_headPtr为nullptr、arraySize为0,彻底避免了未初始化的垃圾值问题 - 简化后的pushBack逻辑统一处理空数组和非空数组的情况,减少分支出错概率
- 析构函数只释放指针数组本身,不会误删外部创建的Edge对象,避免了
_free_dbg错误 - 禁用拷贝构造与赋值,防止浅拷贝导致的重复释放内存问题(如果需要深拷贝,可以自行修改拷贝逻辑)
内容的提问来源于stack exchange,提问作者Hades
相关产品推荐
相关产品推荐

