[英]EXC_BAD_ACCESS, calling getter
我對內存管理不是很好,我希望有人可以幫助我解釋為什么我遇到EXC_BAD_ACCESS(code = 1 ...)錯誤。 Xcode表示在調用getWord()方法時發生錯誤。
我正在實現一個trie數據結構,當我嘗試從節點中獲取一個單詞時發生錯誤。 我認為問題出在我的add或addPhrase方法上,但我不知道發生了什么。 任何建議表示贊賞。
特里和節點類:
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Node
{
private:
string word;
bool endOfSentence = false;
int weight = -1;
public:
vector<Node> children = {};
Node() {
this->setWord("");
}
Node(string s){
this->setWord(s);
}
string getWord(){
return this->word;
}
/*vector<Node> getChildren() { //children private
return this->children;
}*/
void setWord(string s) {
this->word = s;
}
void setEOS(){
this->endOfSentence = true;
}
void setWeight(int weight){
this->weight = weight;
}
};
class Trie
{
public:
Node root = *new Node();
string get(string p) {
string s = "stub";
return s;
}
void add(vector<string> phrase, int weight){
Node current = this->root;
vector<string> sentence = phrase;
int w = weight;
int found = -1;
for (int i = 0; i < current.children.size(); i++) {
if (phrase[0] == current.children[i].getWord()) {
found = i;
}
}
if (found >= 0) {
current = current.children[found];
sentence.erase(sentence.begin());
add(sentence,w);
}
else {
addPhrase(sentence,w);
}
}
void addPhrase(vector<string> phrase, int weight) {
Node current = this->root;
for (int i = 0; i < phrase.size(); i++) {
Node temp = *new Node(phrase[i]);
current.children.push_back(temp);
current = current.children[current.children.size() - 1];
if (i == phrase.size() - 1) {
current.setEOS();
current.setWeight(weight);
}
}
}
};
Main-僅嘗試從第一個節點輸入單詞。
#include "Trie.cpp"
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[]) {
// Initialize trie up here
Trie myTrie = *new Trie();
// parse input lines until I find newline
for(string line; getline(cin, line) && line.compare(""); ) {
stringstream ss(line);
string string_weight;
ss >> string_weight;
int weight = stoi(string_weight);
// I am just going to put these words into a vector
// you probably want to put them in your trie
vector<string> phrase = {};
for(string word; ss >> word;) {
phrase.push_back(word);
}
myTrie.add(phrase, weight);
}
// parse query line
string query;
getline(cin, query);
cout << myTrie.root.children[0].getWord() << endl;
return 0;
}
您是否有使用Java的經驗? 無論如何,關於C ++有幾件重要的事情要注意:簡單的賦值或初始化不會將變量鏈接為對現有對象的引用,並且不需要關鍵字new
來創建新對象。
Node current = this->root;
這條線,在這兩個add
和addPhrase
,創建一個Node
對象,它是你的副本root
節點(孩子和所有)。 因此,您對current
所做的任何操作都不會影響root
。 在main
最后,
cout << myTrie.root.children[0].getWord() << endl;
無效,因為myTrie.root.children
仍然為空,可能會導致崩潰(除非我錯過了先前的問題)。
C ++中的new
關鍵字創建一個具有動態存儲持續時間而不是通常的自動存儲持續時間的對象,這意味着該對象不會由於任何原因被破壞,除非您在指向該對象的指針上使用delete
關鍵字。 所以任何時候你做類似的事情
Trie myTrie = *new Trie();
該程序會創建一個沒有名字的Trie
對象,因為它是new
,然后通過從該對象復制而創建myTrie
對象,但是第一個對象將在程序的其余部分存在,並被視為“泄漏”。 除了形式不正確外,還有太多的泄漏,這將增加程序對計算機內存的使用,而這種方式在程序停止之前是無法逆轉的。 要默認構造一個Trie
對象,只需編寫即可:
Trie myTrie;
在add
和addPhrase
,您希望變量current
與不同的現有Node
對象相關,而不是成為在功能持續時間addPhrase
在的獨立Node
。 這實際上是原始指針的用例:
void addPhrase(vector<string> phrase, int weight) {
Node* current = &this->root;
for (int i = 0; i < phrase.size(); i++) {
Node temp(phrase[i]);
current->children.push_back(temp);
current = ¤t->children.back();
if (i == phrase.size() - 1) {
current->setEOS();
current->setWeight(weight);
}
}
}
(請注意current->children.back()
是說current->children[current->children.size()-1]
一種簡短方法。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.