0

我以前从未见过这种情况。比较两个整数时出现段错误。

编辑:忘记包括最令人沮丧的部分:它在 DDD 中运行良好,所以我无法调试它。

这是我的 gdb 会话回溯段错误:

> 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 的 decompress 部分:

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));
        }
}

谢谢大家!段错误已修复,但现在我的程序的一半显然依赖于损坏的代码,所以回到 DDD。

4

4 回答 4

2

根据您的堆栈跟踪,hnis ...,这表明它可能指向错误的内存(并且鉴于您遇到了段错误,几乎可以肯定它是)。您确定huffnode传递给运算符重载的内容有效吗?是否已初始化?

进一步检查您的堆栈跟踪,n在您的minheap<huffnode>::add函数中也是无效的,这意味着add正在传递一个 invalid huffnodeadd看起来它是从 调用的decompress,并且由于decompress不接受任何参数,因此很可能在那里您将无效传递huffnodeadd.

鉴于add直接传递了huffnode构造函数的返回值,看起来它不会得到一个无效的对象,所以...堆栈跟踪中的可能会产生误导。

我要检查的下一个问题是您的比较heap[index] < heap[(index + 1)/1 - 1]。请注意,如果indexis 0,则第二个运算符将为heap[-1],这是无效的。你能确保index永远不会0或更少吗?

作为旁注,我想指出整个条件:

heap[index] < heap[(index + 1)/2 - 1] && index != 0

即使index等于也将失败,0因为<将首先评估运算符,从而导致 seg-fault。您应该0在条件之外和之前进行检查,或者作为第一个条件。

最后,如果这是仅在调试器之外表现出来的错误类型,那么print语句将成为您的朋友(粗略,是的,但如果您知道要打印什么,它们可以完成工作)。我建议add在循环的每次迭代中添加打印while,检查是什么indexadd您还可以在地址的开头打印n它,看看它是否看起来像未初始化的内存。鉴于您如何将huffnodes 添加到数据结构中,我很确定您的问题是heap数组中的越界访问。

于 2012-12-03T07:10:01.007 回答
0

它几乎肯定与整数无关。两件事之一可能是无效的:

  1. 参考hn&
  2. this指针。

将两者都打印出来,您会看到两者中的哪一个是罪魁祸首。

编辑:我注意到您在问题中添加了更多代码。以下行有问题:

while(heap[index] < heap[(index + 1)/2 -1] && index != 0) {

由于 to 的参数&&是从左到右检查的,因此您需要交换操作数的顺序以避免在以下情况下越界访问index == 0

while(index != 0 && heap[index] < heap[(index + 1)/2 -1]) {
于 2012-12-03T07:06:40.423 回答
0

您的参考hn无效(可能NULL)因此您遇到分段错误的原因。

于 2012-12-03T07:10:37.057 回答
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]

is 为 执行index == 0,相当于

 heap[index] < heap[-1]

尝试使用索引访问不存在的元素-1是导致崩溃的原因。


支票

if(index == 0) return;

您显然“添加”来解决此问题并不能解决任何问题。它只能捕捉index最初为 0 的情况。但是在循环的迭代过程中,它没有捕捉到index稍后变为 0 的情况。

删除这个无意义if的,然后再次交换循环标题中的比较。

于 2012-12-03T07:30:39.723 回答