C++ 基于比较的Seg断层作用
我以前从未见过这种情况。当比较两个整数时,我是seg错误 编辑:忘了包括最令人沮丧的部分:它在DDD中运行良好,所以我无法调试它 以下是我的gdb会话回溯seg故障:C++ 基于比较的Seg断层作用,c++,gdb,segmentation-fault,C++,Gdb,Segmentation Fault,我以前从未见过这种情况。当比较两个整数时,我是seg错误 编辑:忘了包括最令人沮丧的部分:它在DDD中运行良好,所以我无法调试它 以下是我的gdb会话回溯seg故障: > Reading symbols from /home/michael/ecs60/hw3/3/huffman...done. [New LWP 4109] warning: Can't read pathname for load map: Input/output error. Core was generated
> Reading symbols from /home/michael/ecs60/hw3/3/huffman...done.
[New LWP 4109]
warning: Can't read pathname for load map: Input/output error.
Core was generated by `./huffman -d'.
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040123a in huffnode::operator< (this=0x1e39010, hn=...)
at huffnode.h:54
54 if(weight < hn.weight) {
(gdb) bt
#0 0x000000000040123a in huffnode::operator< (this=0x1e39010, hn=...)
at huffnode.h:54
#1 0x00000000004021f4 in minheap<huffnode>::add (this=0x7fff15de7490,
n=...) at minheap.h:65
#2 0x0000000000401cb4 in decompress () at main.cpp:198
#3 0x00000000004012bb in main (argc=2, argv=0x7fff15de75f8)
at main.cpp:41 <
>从/home/michael/ecs60/hw3/3/huffman读取符号…完成。
[新LWP 4109]
警告:无法读取加载映射的路径名:输入/输出错误。
核心由“./huffman-d”生成。
程序以信号11终止,分段故障。
#huffnode中的0 0x000000000040123a::运算符<(此值=0x1e39010,hn=…)
在哈夫诺德。h:54
54如果(重量
以下是违规代码:
bool huffnode::operator<(const huffnode& hn) {
if(weight < hn.weight) {
return true;
} else if(weight == hn.weight) {
return small < hn.small;
} else {
return false;
}
};
template<class T>
void minheap<T>::add(T n) {
if(size + 1 > capacity)
incCapacity();
heap[size] = n;
int index = size;
if(index == 0) return;
while(heap[index] < heap[(index + 1)/2 -1] && index != 0) {
swap(index, ((index+1)/2 - 1));
index = ((index + 1)/2 - 1);
}
size++;
};
bool-huffnode::操作员容量)
incCapacity();
堆[size]=n;
int索引=大小;
如果(指数=0)返回;
while(heap[index]
下面是解压过程中调用minheap::add的部分:
unsigned int freq[NUM_CHARS];
for(int i = 0; i < NUM_CHARS; i++) {
in = getNum();
freq[i] = in;
}
for(int i = 0; i < NUM_CHARS; i++) {
if(freq[i] > 0) {
tree.add(huffnode((int)freq[i], (char) i));
}
}
无符号整数频率[NUM_CHARS];
for(int i=0;i0){
add(huffnode((int)freq[i],(char)i));
}
}
谢谢大家!!seg错误已经修复,但现在我的程序有一半显然依赖于中断的代码,所以回到DDD。它几乎肯定与整数无关。以下两种情况之一可能无效:
hn&
参考李>
此
指针while(heap[index] < heap[(index + 1)/2 -1] && index != 0) {
根据堆栈跟踪,
hn
是…
,这表明它可能指向坏内存(如果您遇到seg故障,几乎可以肯定它是)。您确定传递给运算符重载的huffnode
有效吗?它已经初始化了吗
进一步检查堆栈跟踪,minheap::add
函数中的n
也是无效的,这意味着add
传递了一个无效的huffnode
add
看起来像是从decompress
调用的,而且由于decompress
不接受任何参数,因此它很可能在那里传递一个无效的huffnode
到add
假定add
直接传递huffnode
构造函数的返回值,它看起来不会得到无效的对象,因此堆栈跟踪中的…
可能会产生误导
我要检查的下一个问题是比较heap[index]
。请注意,如果索引
为0
,则第二个运算符将为堆[-1]
,这是无效的。您能否确保索引
永远不会小于0
作为旁注,我想指出整个条件:
heap[index] < heap[(index + 1)/2 - 1] && index != 0
heap[index]
即使
索引
等于0
也会失败,因为您的参考hn
无效(可能NULL
),因此您会出现分段错误。问题是您在循环条件下的比较顺序
while(heap[index] < heap[(index + 1)/2 -1] && index != 0)
在原始变体中,第一次比较
heap[index] < heap[(index + 1)/2 -1]
试图使用索引-1
访问不存在的元素是导致崩溃的原因
支票
if(index == 0) return;
你显然是为了解决这个问题而“添加”的,这并不能解决任何问题。它只能捕获index
最初为0的情况。但是在循环的迭代过程中,index
变为0时,它不会捕捉到这种情况
如果
,请删除此无意义的,然后再次交换循环标题中的比较。我添加了一个检查,以确保&hn不为空。。。如果它在DDD中运行良好,我不知道如何调试它。(gdb)print hn\n$4=(const huffnode&)@0x1e38ff0:这是否意味着hn引用无效?@mcnnowak:是的,它是一个错误的引用。我真的不知道如何修复它。十,。x@mcnnowak在比较两个huffnode
s的地方张贴代码。我是否可以访问我存储T变量的数组中超出范围但仍在页面上的位置?@mcnnowak查看我的更新答案。传递给add
的huffnode
也无效,因此问题出现在调用add
的任何地方,很可能出现在解压缩中。也发布该代码。在minheap:中添加了索引==0的检查:add@mcnnowak:您的支票没有任何变化<代码>索引
稍后在循环迭代期间变为0。您必须交换循环头中的条件。只是想一想:您可能需要先将索引
与0进行比较,然后检查堆条目。如果为0,则在检查边界之前,代码已将堆[0]
与堆[-1]
进行比较。(在本例中,可能不是您的SEGFULT的原因,但从技术上讲,它仍然是错误的。)
heap[index] < heap[(index + 1)/2 -1]
heap[index] < heap[-1]
if(index == 0) return;