我以前从未见过这个。比较两个整数时,我会出现断层错误。
编辑:忘了包含最令人沮丧的部分:它在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 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 <
以下是有问题的代码:
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++;
};
以下是称为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));
}
}
谢谢大家! seg故障是固定的,但现在我的程序的一半显然依赖于破坏的代码,所以回到DDD。
答案 0 :(得分:2)
根据你的堆栈跟踪,hn
是...
,这表明它可能指向坏内存(并且鉴于你得到了一个seg-fault,几乎可以肯定它是)。您确定传递给运算符重载的huffnode
是否有效?是否已初始化?
进一步检查您的堆栈跟踪,n
函数中的minheap<huffnode>::add
也无效,这意味着add
传递了无效的huffnode
。 add
似乎是从decompress
调用的,并且由于decompress
不接受任何参数,因此您可能会将无效的huffnode
传递给add
}。
鉴于add
直接传递huffnode
构造函数的返回值,看起来它不会得到无效对象,所以可能是堆栈跟踪中的...
是误导。
我要检查的下一个问题是你的比较heap[index] < heap[(index + 1)/1 - 1]
。请注意,如果index
为0
,则第二个运算符为heap[-1]
,这是无效的。您能确保index
永远不会0
或更少吗?
作为旁注,我想指出整个条件:
heap[index] < heap[(index + 1)/2 - 1] && index != 0
即使index
等于0
,也会失败,因为<
运算符将首先被评估,从而导致seg-fault。您应该在条件之外和之前进行0
检查,或作为第一个条件。
最后,如果这是只在调试器之外显示的bug类型,则print
语句将成为您的朋友(粗略,是的,但如果您知道要打印的内容,他们可以完成工作) 。我建议在add
循环的每次迭代中向while
添加打印件,检查index
是什么。您还可以在add
的开头打印n
的地址,看看它是否看起来像未初始化的内存。鉴于您如何将huffnode
添加到数据结构中,我很确定您的问题是heap
数组中的越界访问权限。
答案 1 :(得分:0)
它几乎肯定与整数无关。其中一件事可能无效:
hn&
参考; this
指针。打印出两者,你会看到两者中的哪一个是罪魁祸首。
修改:我注意到您在问题中添加了更多代码。以下行存在问题:
while(heap[index] < heap[(index + 1)/2 -1] && index != 0) {
由于&&
的参数从左到右进行检查,因此在index == 0
时需要交换操作数的顺序以避免越界访问:
while(index != 0 && heap[index] < heap[(index + 1)/2 -1]) {
答案 2 :(得分:0)
您的引用hn
无效(可能是NULL
),因此您会收到分段错误。
答案 3 :(得分:0)
问题是您在周期条件中的比较顺序
while(heap[index] < heap[(index + 1)/2 -1] && index != 0)
您应该先index != 0
比较
while(index != 0 && heap[index] < heap[(index + 1)/2 -1])
在原始版本中进行第一次比较
heap[index] < heap[(index + 1)/2 -1]
是index == 0
执行的,相当于
heap[index] < heap[-1]
尝试访问索引为-1
的不存在的元素是造成崩溃的原因。
支票
if(index == 0) return;
你显然“添加”来解决这个问题并没有解决任何问题。它只能捕获最初index
为0时的情况。但是,在循环的迭代期间,index
稍后变为0时,它不会捕捉到这种情况。
删除这个毫无意义的if
,并再次交换循环标题中的比较。