尝试获取向量的大小会导致段错误

时间:2014-08-29 04:07:53

标签: c++ segmentation-fault

我一直试图实施Heap数据类型,而且我已经碰壁了。

由于之前的许多答案都要求使用moar代码,因此它是:

#include <iostream>
#include <vector>
#include <iomanip>

using namespace std;

template <typename T> void display_array(vector<T> arr, bool endline = true)
{
    cout << arr.size() << endl;
    for (int i = 0; i < arr.size() - 1; i++) cout << arr[i] << ", ";
    cout << arr[arr.size() - 1];
    if(endline) cout << endl;
}

template <class T> class Heap
{
    //typedef T Node;
//    setw(...);
//private:

public:
    vector<T>* elems;
    Heap() : elems(nullptr)
    {
        this->elems = new vector<T>;
    }

    Heap(vector<T> e)
    {
        this->elems = new vector<T>(e);
    }

    Heap(vector<T>* e)
    {
        this->elems = e;
    }

    Heap(Heap<T>& h)
    {
        this->elems = new vector<T>(h.elems);
    }

    ~Heap()
    {
        delete elems;
    }

    T elemAt (int index)
    {
        return (*(this->getElems())) [index];
    }

    vector<T>* getElems()
    {
        return this->elems;
    }

    int parent (int index)
    {
        return index / 2;
    }

    long getSize()
    {
        return this->getElems()->size();
    }

    int left (int index)
    {
        return 2 * index;
    }
    T leftElem (int index)
    {
        return this->elems [2 * index];
    }

    int right (int index)
    {
        return 1 + 2 * index;
    }
    T rightElem (int index)
    {
        return this->elems [1 + 2 * index];
    }

    bool withinHeap (int index)
    {
        return index <= (this->getSize());
    }

    void maxHeapify(int index)
    {
        int largest = index;
        int l = left(index);
        int r = right(index);

        if (withinHeap(l) && elemAt(l) > elemAt(index))
        {
            if (withinHeap(r) && elemAt(r) > elemAt(l))
            {
                largest = r;
            }
            largest = l;
        }

        if (largest != index)
        {
            int temp = elemAt(index);
            elemAt(index) = elemAt(largest);
            elemAt(largest) = temp;
            delete temp;
        }
        /* or return withinHeap(l) && elemAt(l) > elemAt(index) ? withinHeap(r) && elemAt(r) > elemAt(l) ? r : l : index; :) */
    }

    void display(int current, int indent)
    {
        if(withinHeap(left(current))) display(left(current), indent + 4);
        if (indent > 0) cout << setw(indent) << " ";
        cout << elemAt(current) << endl;
        if(withinHeap(right(current))) display(right(current), indent + 4);
    }
};

int main()
{
    vector<int> vec {2, 5, 4, 12, 3, 9};
    Heap<int>* h = new Heap<int>(vec);
    display_array(*h->getElems());

    h->display(0, 0);


    return 0;
}

最后一个语句(h->display(0,0))会导致段错误。我已将其缩小到getSize()函数。

在gdb中,print this.elemsprint *this.elems是可以的(它们会返回对象跟踪或者它们被调用的任何内容),但是当我键入print *this.elems->size() gdb回复

  

Cannot access memory at address 0xbf7fffef

我对C ++和gdb以及所有内容都很陌生。这里有什么问题?

1 个答案:

答案 0 :(得分:2)

根据C ++技术(全部有效)对代码的所有评论,问题似乎是你的display函数导致堆栈溢出。

如果您使用left()实际执行的操作替换left()的来电,您可以清楚地看到它:

void display(int current, int indent)
{
    if (withinHeap(2 * current)) 
        display(2 * current, indent + 4);
    //...
}

如果我们调用display(0, 0);,那么函数将无法返回,因为您在循环中使用相同的参数值调用display

withinHeap除了检查参数是否在边界内之外没有做任何事情,并且不以任何方式更改Heap对象。由于0在范围内,因此对withinHeap的调用始终返回true。因此,从这个功能的开始你就遇到了麻烦。

我不会讨论如何解决这个问题,因为这是一个算法问题,而不是C ++问题。但是我指出的是你的代码导致错误的地方。