问题
I'm having trouble with a segmentation fault caused by the following line:
heapVec[currentsize] = *(new Node(d));
What am I doing wrong here?
#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);
}
回答1:
A vector doesn't grow automatically when you write out of its bounds using subscript operator. To insert to the end of the vector (increasing its size) use this:
heapVec.push_back(Node(d));
Also don't use *(new Node(d)), it won't segfault, but its a memory leak.
回答2:
Before you access a vector by index you need to allocate space for it
heapVec[currentsize] = *(new Node(d));
heapVec.resize(currentsize + 1) should do it. It will ensure that heapVec has at least currentsize + 1 elements and you can access currentsize.
One way to avoid this is by modifying your function. As you only are adding to the end of the vector.
void Heap::insert(int d) {
heapVec.push_back( Node(d) );
currentsize++;
}
Please note that you have vector<Node> and not vector<Node*> so you don't need the new call.
Also vector has a size() method so you don't need to duplicate it by having your own currentSize
回答3:
First, you're writing outside the range of the vector, which is causing the segmentation fault. You need to either resize the vector to be large enough to contain it, or use push_back() to resize it for you.
Second, you have a memory leak - you're creating a Node with new for no good reason, then copying it into the vector, then losing the pointer and so never deleting the first object.
What you want is
heapVec.push_back(Node(d));
or in C++11
heapVec.emplace_back(d);
I would also get rid of your redundant currentsize variable and use heapVec.size() instead. Also, don't use new to create the local heap in main(); in general don't use new unless you really have to, and when you do, always use smart pointers or very carefully written code to make sure the object is deleted.
回答4:
I am pretty sure that you got this error because you tried to write out of vector's boundaries. Don't use array syntax (although you're allowed) for operations on vector: in Heap::insert() use heapVec.push_back().
Another thing is that you should not bother using Node type if it contains only int member. Why not just having vector<int>?
You can simplify your class further. When you already have std::vector, your currentsize member is redundant (unnecessary) as vector::size() will tell you the current size of it.
回答5:
What am I doing wrong here?
A few different things, including the bug that results in your crash. See my comments below.
#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);
}
回答6:
There are two errors you are doing: The first is the problem you have, and it's that you insert into a specific place in heapVec without allocating memory for it. This is solved either by calling heapVec.reserve(...) in the Heap constructor, or by calling heapVec.push_back(Node(d)) in insert.
The other problem is that when inserting nodes into the vector, you allocate new node and get the contents of it, which will make a copy that is stored in the vector. But you don't store the actual allocated pointer, which means you have a memory leak. You should not allocate in this case.
来源:https://stackoverflow.com/questions/8138071/segmentation-fault-in-c-using-vectors