簡體   English   中英

使用向量在C ++中進行分段錯誤

[英]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()為您調整大小。

其次,你有一個內存泄漏 - 你沒有充分的理由創建一個newNode ,然后將其復制到向量中,然后丟失指針,所以永遠不要刪除第一個對象。

你想要的是什么

heapVec.push_back(Node(d));

或者在C ++ 11中

heapVec.emplace_back(d);

我也會擺脫你的冗余currentsize變量,而是使用heapVec.size() 另外,不要使用newmain()創建本地堆; 一般情況下不要使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM