我有一个类Word,它包含一个字符串和一个结构向量,每个结构包含一个指向容器类的指针,如下所示:
struct doc {
Document* d;
int timesMentioned = 0;
};
我有一个输出函数,可以在Word的doc向量中输出每个Word的字符串和每个doc的键。 (d1,d2,d3等)
每当我将所有这些输出到文件时,它看起来像这样:
foo = d3,
bar = d3,
foobar = d3,
etc.
每个Word只输出d3(从给定输入文件循环到最后一个文档。如果需要,我可以发布代码)
奇怪的是,每当我将它输出到控制台时,它都能正常工作。与每个Word关联的文档正确输出。知道为什么会这样吗?我认为它可能是一个悬垂的指针,但它正确地输出到控制台是好奇的。如果需要,我可以发布添加文档功能或更多代码。
以下是Word类的代码:
void Word::createWord(string str) {
removePunctuation(str);
toLower(str);
word = str;
}
void Word::addDoc(Document& d) {
doc newDoc;
newDoc.d = &d;
newDoc.timesMentioned++;
docs.push_back(newDoc);
}
vector<doc> Word::getDocs() {
return docs;
}
string Word::getWord() {
return word;
}
//Formatting the string, should be irrelevant to this question
void Word::removePunctuation(string& str) {
string temp = "";
for(int i = 0; i < str.length(); i++) {
bool punctual = false;
for(int k = 0; k < 42; k++)
if(str[i] == punctuals[k]) punctual = true;
if(!punctual) temp += str[i];
}
str = temp;
}
void Word::toLower(string& str) {
string temp = "";
for(int i = 0; i < str.size(); i++) {
char c = str[i];
temp += tolower(c);
}
str = temp;
}
这里是单词/文档被实例化并添加到向量中的地方:
void InvertedFileIndex::parseFile(string fileName) {
fstream fin, fout;
fin.open(fileName.c_str(), fstream::in);
if(fin.is_open()) {
//Parse input into a single string to the XMLParsing
xml_document<> doc;
string str, parse = "";
while(fin >> str)
parse += str + " ";
doc.parse<0>(&parse[0]);
xml_node<>* root;
root = doc.first_node("mediawiki");
//Iterate through each page
int i = 1;
for (xml_node<>* page = root->first_node("page"); page; page = page->next_sibling()) {
Document d;
Word w;
string docName = "d" + intToStr(i);
xml_node<>* title = page->first_node("title");
d.setTitle(page->first_node("title")->value());
d.setKey(docName);
//Find text from document
xml_node<>* revision = page->first_node("revision");
xml_node<>* text = revision->first_node("text");
d.setText(text->value());
string docText = text->value();
////Begin parsing text into words
stringstream ss(docText); //create a string stream so we can break it into tokens
string item;
while (getline(ss, item, ' ')) {
Word w;
w.createWord(item);
w.addDoc(d);
toks.push_back(w);
}
documents.push_back(d);
writeToIndex();
i++;
}
fin.close();
}
else
cout << "The sample file " << fileName << "could not be opened." << endl;
}
这是输出代码:
void InvertedFileIndex::writeToIndex() {
fstream fout;
fout.open("index.txt", fstream::out);
if(fout.is_open()) {
for(int i = 0; i < toks.size(); i++) {
fout << toks[i].getWord() << " = ";
cout << toks[i].getWord() << " = ";
for(int j = 0; j < toks[i].getDocs().size(); j++) {
fout << toks[i].getDocs()[j].d->getKey();
cout << toks[i].getDocs()[j].d->getKey();
fout << ", ";
cout << ", ";
}
fout << endl;
cout << endl;
}
fout.close();
}
else
cout << "Index file could not be opened." << endl;
}
答案 0 :(得分:2)
请注意,我正在保存指向超出范围的对象的指针。基本上你的代码是
while (...)
{
Document d;
...
w.add(d); // add takes a reference and stores pointer to d
}
// sometime later
writeToIndex();
显然,当你编写toToIndex时,所有在while循环中创建的文档对象都已被销毁。所以你有指向不再存在的对象的指针。如果你想存储指针,那么你应该在某处动态分配对象。