输出到文件给出错误的指针值

时间:2013-04-20 02:59:54

标签: c++ file pointers output

我有一个类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;
}

1 个答案:

答案 0 :(得分:2)

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

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

// sometime later
writeToIndex();

显然,当你编写toToIndex时,所有在while循环中创建的文档对象都已被销毁。所以你有指向不再存在的对象的指针。如果你想存储指针,那么你应该在某处动态分配对象。