簡體   English   中英

C ++向量std :: bad_alloc錯誤

[英]C++ vector std::bad_alloc error

我正在嘗試在c ++中實現后綴樹,同時將節點添加到向量列表中,在向樹中添加第三個元素后,它會引發std :: bad_alloc。 我不知道為什么它在第三次之后發生,您能幫我解決這個bad_alloc錯誤嗎?

這是我的代碼:

suffix_tree.cpp

#include <iostream>
#include <fstream>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include "node.h"

using namespace std;

Node build_suffix_tree(string text){
    Node root = Node();
    int n = text.length();
    int count;
    Node * currentNode = &root;
    Node tmpNode;
    string suffix;
    int suffixLen;


    for(int i=0; i<n; i++){
        suffix = text.substr(i,n);
        suffixLen = suffix.length();
        count = 1;
        currentNode = &root;

        while(count <= suffixLen){
            cout << suffix << endl;
            int pos = -1;


            // bad_alloc occurs here
            (*currentNode).addFils(Node(suffix[0], vector<Node>(), i));


            cout << currentNode->getFils().size() << endl;
            currentNode = &currentNode[currentNode->getFils().size() - 1];

            suffix = suffix.substr(1,suffixLen);
            count++;
        }
        cout << "  " << endl;
    }
    return root;
}


int main(){
   string text = "helloeveryone";
   Node root = build_suffix_tree(text);
   return 0;
}

node.cpp

#include <string>
#include <vector>
#include "node.h"

using namespace std;

Node::Node(){
    c = ' ';
    fils = vector<Node>();
    pos = -1;
}

Node::Node(char t, vector<Node> l, int p){
    c = t;
    fils = l;
    pos = p;
}

void Node::addFils(Node n){
    fils.push_back(n);
}

char Node::getString(void){
    return c;
}

vector<Node> Node::getFils(){
    return fils;
}

void Node::setFils(vector<Node> l){
    fils = l;
}

節點

#include <string>
#include <vector>

#ifndef NODE_H
#define NODE_H

class Node
{
public:
    char c;
    std::vector<Node> fils;
    int pos;
    Node();
    Node(char c, std::vector<Node> fils, int p);
    void addFils(Node n);
    char getString(void);
    std::vector<Node> getFils();
    void setFils(std::vector<Node>);
};

#endif // NODE_H

生成文件

CC=g++
CFLAGS= -g
LDFLAGS=
EXEC=suffix_tree

all: $(EXEC)

suffix_tree: suffix_tree.o node.o
$(CC) -o suffix_tree suffix_tree.o node.o $(LDFLAGS)

node.o: node.cpp
$(CC) -o node.o -c node.cpp $(CFLAGS)

suffix_tree.o: suffix_tree.cpp node.h
$(CC) -o suffix_tree.o -c suffix_tree.cpp $(CFLAGS)

clean:
rm -rf *.o

mrproper: clean
rm -rf $(EXEC)

提前致謝。

正如Nemanja Boric在評論中指出的那樣,您正在覆蓋堆棧,因此任何事情都可能發生。 在我的PC上,它恰好在GCC中是bad_alloc ,在clang中是普通的segfault。

仔細觀察這一行:

currentNode = &currentNode[currentNode->getFils().size() - 1];

currentNode是指向Node指針。 在開始時,它指向在堆棧上分配的變量root

在第一次迭代中,它更改為&currentNode[1 -1] ,它等於currentNode 所以什么也沒發生(我想這不是故意的)。

在下一次迭代中,它更改為&currentNode[2 - 1] &currentNode[1] ,它等於&currentNode[1] ,它等於currentNode+1 那是堆棧上的地址,緊跟在root變量之后。 它已分配,但它的值不是Node* 它可以屬於int n; ,但基於編譯器的優化可能會完全不同。

在3.迭代中,當您嘗試將此地址用作Node實例(不是)時,會得到未定義的行為,並且它們實際上可能會發生。 它會殺死貓並燒毀房屋。 因此,您仍然很幸運,只能得到bad_alloc

分配錯誤是因為堆棧/堆已經損壞,所以錯誤應該發生在您指出的代碼行之前。

count== suffixLen時發生錯誤。 以下是您代碼中的代碼段,假設“后綴”為“ ab”,因此“ suffixLen”為2。

在第一個循環之后,count是2,“后綴”是“ b”,在第二個循環中,代碼

suffix = suffix.substr(1,suffixLen);

將失敗並導致內存問題,因為1不在范圍內。 因此,當“后綴”中只剩下一個字符時,您應該處理這種情況

  suffixLen = suffix.length();
    count = 1;
    currentNode = &root;

    while(count <= suffixLen){


        // bad_alloc occurs here
        (*currentNode).addFils(Node(suffix[0], vector<Node>(), i));


        suffix = suffix.substr(1,suffixLen);
        count++;
    }

這是非常錯誤的。

currentNode = &currentNode[currentNode->getFils().size() - 1];

我的猜測是,您期望將currentNode指針移動到列表的下一個元素。 但是,您尚未分配列表。 您將root初始化為Node,然后將currentNode指向root。 除了root + sizeof(Node)之外,沒有分配的內存,該內存實際上存在於堆棧中,但是這無關緊要,因為如果您執行了新的Node(),也會出現相同的問題。

我認為您以為root是某種引導程序或預分配列表,但是我不確定您的意圖是什么。 第一次迭代currentNode-> getFils()。size()返回1且1-1 = 0,因此,currentNode將其指針設置為自身。 在下一次迭代中,currentNode將自身設置為比根目錄高出sizeof(Node)的內存位置,該根目錄位於未知領域。

正如Nemanja Boric指出的那樣,有問題的行是:

currentNode = &currentNode[currentNode->getFils().size() - 1];

在每次迭代中,您要調用currentNode的副本構造函數,並在堆棧中增加一個內存地址,該地址在每一步都增加(currentNode,currentNode + 1,currentNode + 2等),這樣做會破壞Node.fils並且,當您嘗試push_back一個元素時,會得到bad_alloc

另一方面,如果要向fils添加新元素,為什么需要增加對節點的引用? 可能是您想使用鏈接列表嗎?

我在使用push_back()時遇到了同樣的問題。 問題是向量必須在您的內存上有連續的空間才能工作,並且由於您的操作系統按碎片分配內存,因此它可能會分配一個可能無法包含所有向量的空間。 但是,如果您知道向量的最終大小,則可以使用std :: vector :: resize()來幫助操作系統選擇分配向量的最佳位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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