在比较中出现断裂

时间:2012-12-03 07:04:57

标签: c++ gdb segmentation-fault

我以前从未见过这个。比较两个整数时,我会出现断层错误。

编辑:忘了包含最令人沮丧的部分:它在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。

4 个答案:

答案 0 :(得分:2)

根据你的堆栈跟踪,hn...,这表明它可能指向坏内存(并且鉴于你得到了一个seg-fault,几乎可以肯定它是)。您确定传递给运算符重载的huffnode是否有效?是否已初始化?

进一步检查您的堆栈跟踪,n函数中的minheap<huffnode>::add也无效,这意味着add传递了无效的huffnodeadd似乎是从decompress调用的,并且由于decompress不接受任何参数,因此您可能会将无效的huffnode传递给add }。

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

我要检查的下一个问题是你的比较heap[index] < heap[(index + 1)/1 - 1]。请注意,如果index0,则第二个运算符为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)

它几乎肯定与整数无关。其中一件事可能无效:

  1. hn&参考;
  2. this指针。
  3. 打印出两者,你会看到两者中的哪一个是罪魁祸首。

    修改:我注意到您在问题中添加了更多代码。以下行存在问题:

    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,并再次交换循环标题中的比较。