[英]Segmentation fault in C++ using vectors
我遇到由以下行引起的分段錯誤的問題:
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);
}
使用下標運算符寫出其邊界時,向量不會自動增長。 要插入向量的末尾(增加其大小),請使用以下命令:
heapVec.push_back(Node(d));
也不要使用*(new Node(d))
,它不會出現段錯誤,而是內存泄漏。
在通過索引訪問向量之前,您需要為其分配空間
heapVec[currentsize] = *(new Node(d));
heapVec.resize(currentsize + 1)應該這樣做。 它將確保heapVec至少具有大小+ 1個元素,並且您可以訪問currentsize 。
避免這種情況的一種方法是修改你的功能。 因為你只是添加到向量的末尾。
void Heap::insert(int d) {
heapVec.push_back( Node(d) );
currentsize++;
}
請注意,您有vector <Node>而不是vector <Node *>,因此您不需要新的呼叫。
vector也有一個size()方法,所以你不需要通過擁有自己的currentSize來復制它
首先,你是在向量范圍之外寫的,這導致了分段錯誤。 您需要將向量的大小調整為足以包含它,或者使用push_back()
為您調整大小。
其次,你有一個內存泄漏 - 你沒有充分的理由創建一個new
的Node
,然后將其復制到向量中,然后丟失指針,所以永遠不要刪除第一個對象。
你想要的是什么
heapVec.push_back(Node(d));
或者在C ++ 11中
heapVec.emplace_back(d);
我也會擺脫你的冗余currentsize
變量,而是使用heapVec.size()
。 另外,不要使用new
在main()
創建本地堆; 一般情況下不要使用new
除非你真的需要,當你這樣做時,總是使用智能指針或非常仔細編寫的代碼來確保刪除對象。
我很確定你有這個錯誤,因為你試圖寫出矢量的邊界。 不要對vector使用數組語法(盡管你是允許的):在Heap::insert()
使用heapVec.push_back()
。
另一件事是,如果它只包含int
成員,你不應該使用Node
類型。 為什么不只是vector<int>
?
您可以進一步簡化課程。 當你已經有std::vector
,你的currentsize
成員是多余的(不必要的),因為vector::size()
會告訴你當前的大小。
我在這做錯了什么?
一些不同的東西,包括導致崩潰的錯誤。 請參閱下面的評論。
#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);
}
您正在做兩個錯誤:第一個是您遇到的問題,而且您要插入heapVec
的特定位置而不heapVec
分配內存。 這可以通過在Heap
構造函數中調用heapVec.reserve(...)
,或者通過在insert
調用heapVec.push_back(Node(d))
來解決。
另一個問題是,當將節點插入向量時,您將分配新節點並獲取其內容,這將生成存儲在向量中的副本。 但是您不存儲實際分配的指針,這意味着您有內存泄漏。 在這種情況下你不應該分配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.