使用向量在C ++中进行分段错误

时间:2011-11-15 14:40:23

标签: c++ segmentation-fault

我遇到由以下行引起的分段错误的问题:

heapVec[currentsize] = *(new Node(d));

我在这里做错了什么?

#include <vector>
using namespace std;

class Node {
private:
    int data;
public:
    Node(int);
    // ~Node();
};

class Heap {
private:
    vector<Node> heapVec;
    int currentsize;
public:
    Heap();
    // ~Heap();
    void insert(int);
    void extractMin();
    void reduceKey();
};

Node::Node(int d) {
    data = d;
}

void Heap::insert(int d) {
    heapVec[currentsize] = *(new Node(d));
    currentsize++;
}

Heap::Heap() {
    // this is the default constructor
    currentsize = 0;
}

int main() {
    Heap *h = new Heap;
    h->insert(10);
}

6 个答案:

答案 0 :(得分:9)

使用下标运算符写出其边界时,向量不会自动增长。要插入向量的末尾(增加其大小),请使用:

heapVec.push_back(Node(d));

另外不要使用*(new Node(d)),它不会发生段错误,而是内存泄漏。

答案 1 :(得分:2)

在按索引访问向量之前,您需要为其分配空间

 heapVec[currentsize] = *(new Node(d));

heapVec.resize(currentsize + 1)应该这样做。它将确保heapVec至少具有大小+ 1个元素,并且您可以访问 currentsize

避免这种情况的一种方法是修改你的功能。因为你只是添加到向量的末尾。

void Heap::insert(int d) {
    heapVec.push_back( Node(d) );
    currentsize++;
}

请注意,您有向量&lt;节点&gt; 而不是向量&lt;节点*&gt; ,因此您不需要来电

此外,vector还有 size()方法,因此您无需通过拥有自己的 currentSize

来复制它

答案 2 :(得分:1)

首先,你是在矢量范围之外写的,这导致了分段错误。您需要将矢量调整为足够大以包含它,或者使用push_back()为您调整大小。

其次,你有内存泄漏 - 你没有充分的理由创建Node new,然后将其复制到向量中,然后丢失指针,从而永远不会删除第一个对象

你想要的是

heapVec.push_back(Node(d));

或在C ++ 11中

heapVec.emplace_back(d);

我也会删除多余的currentsize变量并改用heapVec.size()。另外,不要使用newmain()中创建本地堆;通常不要使用new除非你真的需要,当你这样做时,总是使用智能指针或非常仔细编写的代码来确保删除对象。

答案 3 :(得分:0)

我很确定你有这个错误,因为你试图写出矢量的边界。不要使用数组语法(尽管你被允许)对vector进行操作:在Heap::insert()中使用heapVec.push_back()

另一件事是,如果只包含Node成员,则不应该使用int类型。为什么不只是vector<int>

您可以进一步简化课程。如果您已经std::vector,则currentsize成员是多余的(不必要的),因为vector::size()会告诉您当前的大小。

答案 4 :(得分:0)

  

我在这里做错了什么?

一些不同的东西,包括导致崩溃的错误。请参阅下面的评论。

#include <vector>

// Never, ever, say "using namespace std;" even if (especially if) your textbook says to.
// using namespace std;
using std::vector;

class Node {
private:
    int data;
public:
    // Prefer to define small functions in-class so that they are automatically inline
    // Prefer initialization list to assignment. This is mostly style in your case, but
    // does matter in more complex cases.
    Node(int d) : data(d) {}
    // ~Node();
};

class Heap {
private:
    vector<Node> heapVec;
    // int currentsize;  "currentsize" is redundant, and thus error-prone.
    // heapVec always knows what size it is, so just ask it whenever you need to know.
public:
    // In this trivial example, with currentsize gone, you don't need any constructor.
    // Heap();
    // ~Heap();
    void insert(int);
    void extractMin();
    void reduceKey();
};

void Heap::insert(int d) {
    // This is your crash bug -- std::vector::operator[] doesn't automatically extend
    // the size of the vector (unlike, say, std::map::operator[], which does).
    // Also, your use of "new" here is unconventional, and buggy. You have a memory leak.
    // It is possible to write perfectly useful C++ programs while never invoking "new"
    // directly.
    // heapVec[currentsize] = *(new Node(d));
    // currentsize++;

    // Instead, use std::vector::push_back() or std::vector::insert(), *and* don't call
    // new.
    heapVec.push_back(Node(d));
}


int main() {
    // In this example (and, I bet, in your real-world program), you don't need "new"
    Heap h;
    h.insert(10);
}

答案 5 :(得分:-1)

您正在做两个错误:第一个是您遇到的问题,而且您要插入heapVec中的特定位置而不为其分配内存。这可以通过致电heapVec.reserve(...)构造函数中的Heap或致电heapVec.push_back(Node(d))中的insert来解决。

另一个问题是,当将节点插入向量时,您将分配新节点并获取其内容,这将生成存储在向量中的副本。但是您不存储实际分配的指针,这意味着您有内存泄漏。在这种情况下你不应该分配。