我遇到由以下行引起的分段错误的问题:
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 :(得分: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()
。另外,不要使用new
在main()
中创建本地堆;通常不要使用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
来解决。
另一个问题是,当将节点插入向量时,您将分配新节点并获取其内容,这将生成存储在向量中的副本。但是您不存储实际分配的指针,这意味着您有内存泄漏。在这种情况下你不应该分配。