堆实现中的奇怪分段错误
Strange Segmentation Fault in Heap Implementation
下面是我为使用自己的堆实现编写的驱动程序。
#include<iostream>
#include"Heap.h"
int main(){
Heap h(30);
h.insert(1);
h.insert(3);
h.insert(5);
h.insert(6);
h.insert(5);
h.insert(8);
h.display();
std::cout<<h.extractMin(); // Statement 1
h.display();
}
这给出了所需的结果:
========= Heap Contents =========
1 3 5 6 5 8
1
========= Heap Contents =========
3 6 5 8 5
但是,如果我将statement 1
更改为:
std::cout<<"Min: "<<h.extractMin();
代码开始给出分段错误。同样,如果我将statement 1
更改为
int z = h.extractMin();
代码仍然给出分段错误。这让我想看看我在extractMin()
中是否做错了什么。以下是我对extractMin()
的定义:
int Heap::extractMin()
{
int min = this -> arr[0];
this -> arr[0] = this -> arr[heapSize];
heapSize -= 1;
heapify(0);
return min;
}
为了完整起见,下面是我对heapify()
:的定义
void Heap::heapify(int index){
if(index > this -> heapSize)
return;
int smallest = index;
int l = leftChild(index);
int r = rightChild(index);
if(l <= heapSize && arr[l] < arr[index])
smallest = l;
if(r <= heapSize && arr[r] < smallest)
smallest = r;
if(smallest != index){
arr[smallest] = arr[smallest] ^ arr[index];
arr[index] = arr[smallest] ^ arr[index];
arr[smallest] = arr[smallest] ^ arr[index];
heapify(smallest);
}
}
知道发生了什么事吗?我无法理解分割错误背后的原因。有什么明显我遗漏的吗?
谢谢!
附加1:
h.getHeapSize()
和h.getArrSize()
也会发生这种情况,这让我认为问题在于其他方面,而不是函数。
附加2:
整个代码如下:
#include<iostream>
#include<cmath>
class Heap{
private:
int* arr;
int size;
int heapSize;
public:
Heap(int = 8);
Heap(int*, int size);
int* initArr(int size);
void setSize(int);
int getSize();
int getHeapSize();
void setHeapSize(int);
int leftChild(int);
int rightChild(int);
int parent(int);
void heapify(int);
void buildHeap();
void insert(int);
int extractMin();
void display() const;
};
Heap::Heap(int size){
initArr(size);
this -> size = size;
this -> heapSize = -1;
}
Heap::Heap(int* arr, int size){
this -> arr = arr;
this -> size = size;
this -> heapSize = size - 1;
buildHeap();
}
int* Heap::initArr(int size){
int* arr = new int[size];
return arr;
}
void Heap::setSize(int size){
if(size > this -> heapSize)
this -> size = size;
}
int Heap::getSize(){
return this -> size;
}
void Heap::setHeapSize(int heapSize){
this -> heapSize = heapSize;
}
int Heap::getHeapSize(){
return this -> heapSize;
}
int Heap::leftChild(int index){
return 2*index + 1;
}
int Heap::rightChild(int index){
return 2*index + 2;
}
int Heap::parent(int index){
return ceil(index >> 1) - 1;
}
void Heap::heapify(int index){
if(index > this -> heapSize)
return;
int smallest = index;
int l = leftChild(index);
int r = rightChild(index);
if(l <= heapSize && arr[l] < arr[index])
smallest = l;
if(r <= heapSize && arr[r] < smallest)
smallest = r;
if(smallest != index){
arr[smallest] = arr[smallest] ^ arr[index];
arr[index] = arr[smallest] ^ arr[index];
arr[smallest] = arr[smallest] ^ arr[index];
heapify(smallest);
}
}
void Heap::buildHeap(){
for(int i = heapSize/2 - 1; i >= 0; i-- )
heapify(i);
}
void Heap::insert(int val){
heapSize += 1;
int loc = heapSize;
arr[heapSize] = val;
int p;
while((p = arr[parent(heapSize)]) > val){
arr[loc] = arr[p] ^ arr[loc];
arr[p] = arr[p] ^ arr[loc];
arr[loc] = arr[p] ^ arr[loc];
}
}
int Heap::extractMin(){
//int temp = arr[0];
//arr[0] = arr[heapSize];
//arr[heapSize] = temp;
int min = arr[0];
arr[0] = arr[heapSize];
heapSize -= 1;
heapify(0);
//return arr[heapSize + 1];
return min;
}
void Heap::display() const{
std::cout<<"n========= Heap Contents =========n";
for(int i = 0; i <= heapSize; i++)
std::cout<<arr[i]<<'t';
std::cout<<'n';
}
存在许多问题。
首先,采用int
参数的构造函数不会初始化arr
成员,它会分配内存并将其分配给本地指针变量,然后返回该变量,但忽略返回值
您必须将其存储在成员变量中(将局部变量命名为与成员相同通常是一个非常糟糕的主意。)
一旦修复:在第一次插入时,h.insert(1);
,parent(heapSize)
为-1。
由于您使用它在数组中进行索引,因此程序具有未定义的行为,并且所有赌注都已取消;该程序不是有效的C++程序。
可能还有其他问题,但这些问题是最明显的。
根据您在这里发布的内容,堆大小的处理不当是罪魁祸首。所有涉及heapSize
的测试似乎都没有考虑到基于零的访问。你真的应该改变这一点,因为这会导致很多不合乎逻辑的后果:heapSize初始化为-1
吗?
关于调试:
- 轻松地添加更多的null和边界检查(不仅对
heapSize
,而且对0) - 尝试减少测试集(它是否与一个项目崩溃?)并尝试手动或使用gdb跟踪控制流
编辑
错误在parent()
中。试试调试技巧。
相关文章:
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?