2011-11-15 25 views
2
我在与造成以下行分段错误麻烦

分段故障++使用矢量

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

代码'*(new Node(d))'完全错误。它分配Node类的对象,并忘记了指针。这是内存泄漏的定义。您必须更改'vector heapVec;'向'vector heapVec;'或使用类似'boost :: ptr_vector heapVec;'的东西。 – Arpegius

+0

请勿使用矢量。您很可能最终会发生内存泄漏,因为您将不得不手动删除每个向量成员。 只要做,Dani在下面说,你很好。 – Ben

+0

+1,用于演示您遇到的问题的完整,最简单的程序。请参阅http://sscce.org为什么这是有价值的原因。 –

回答

8

当你写出来的使用标其边界的矢量不会自动增长运营商。要插入到向量的末尾(增加其大小)使用此:

heapVec.push_back(Node(d)); 

也不要使用*(new Node(d)),也不会出现段错误,但它的内存泄漏。

2

之前通过索引来访问一个向量,你需要为它

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

heapVec.resize(currentsize + 1)应该这样做分配空间。它将确保heapVec至少具有currentize + 1元素,并且您可以访问currentise

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

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

请注意,您必须矢量<节点>,而不是矢量<节点*>,所以你不需要电话。

而且载体具有大小()方法,所以你并不需要通过拥有自己的currentSize复制它

+0

我明白你的意思,但这是给我以下内容: minheap.cpp:33:错误:没有匹配函数调用'节点::节点()' minheap.cpp:28:注意:候选人是: Node :: Node(int) minheap.cpp:8:note:Node :: Node(const Node&) –

+0

你需要一个默认的构造函数来存放你在std :: vector中的任何东西。 –

+0

@ DanielO'Connor:当然,您需要为Node定义默认构造函数。没有一个,你不能使用节点的std :: vector。 – Arne

-1

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

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

+2

'reserve()'没有帮助,除了用更微妙的未定义行为来替换分段错误 - 访问超出数组末尾的对象仍然是非法的。你需要在访问它们之前调整大小()。 –

1

首先,你写的是向量的范围之外,这是导致分段错误。您需要调整矢量的大小以容纳它,或者使用push_back()来为您调整大小。

其次,你有一个内存泄漏 - 你创建一个Nodenew没有什么好的理由,然后将其复制到向量中,然后丢失指针,因此从不删除第一个对象。

你想要的是

heapVec.push_back(Node(d)); 

或C++ 11

heapVec.emplace_back(d); 

我也想摆脱你的多余currentsize变量和使用heapVec.size()代替。另外,请勿使用newmain()中创建本地堆;一般情况下不要使用new,除非你真的必须,而且当你这样做的时候,总是使用智能指针或非常仔细的代码来确保删除对象。

0

我很确定你得到这个错误,因为你试图写出矢量的边界。不要使用数组语法(虽然您可以)对矢量进行操作:在Heap::insert()中使用heapVec.push_back()

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

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

0

What am I doing wrong here?

一些不同的事情,包括导致您崩溃的错误。看到我的评论如下。

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