0

我有一个 Word 类,它包含一个字符串和一个结构向量,每个结构都包含一个指向容器类的指针,如下所示:

struct doc {
    Document* d;
    int timesMentioned = 0;
};

我有一个输出函数,可以输出每个 Word 的字符串和 Word 的文档向量中的每个文档的键。(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;
}
4

1 回答 1

2

在我看来,您正在保存指向超出范围的对象的指针。基本上你的代码是

while (...)
{
    Document d;
    ...
    w.add(d); // add takes a reference and stores pointer to d
}

// sometime later
writeToIndex();

显然,当您开始 writeToIndex 时,在 while 循环中创建的所有文档对象都已被销毁。所以你有指向不再存在的对象的指针。如果要存储指针,则应在某处动态分配对象。

于 2013-04-20T06:29:28.323 回答