c++ - 具有 ifstream 成员的内部类的构造函数返回无效的 fstream

标签 c++ access-violation ifstream

我有一个带有内部类的类,它有一个成员 ifstream。执行代码时,在 if(!datafile->eof()) 处的 TestDataHelper::getNextLine() 中抛出 AccessViolationException。

调试显示构造函数工作正常。创建文件并读取第一行。但是当我在分配完成后检查数据文件时(在 TestDataHelper helper = TestDataHelper("data.csv"); 之后),数据文件变成了一个无效指针。

代码:

IfstreamTester.h

#include <vector>
#include <iostream>
#include <string>
#include <sstream>

class IfstreamTester
{
public:
    IfstreamTester(void);
    ~IfstreamTester(void);

    void doStuff();

private:
    std::ifstream file;

    class TestDataHelper{
    private:
        std::ifstream *datafile;
    public:
        TestDataHelper(std::string filename);
        ~TestDataHelper();
        std::vector<double>* getNextLine();
    };
};

IfstreamTester.cpp

#include "IfstreamTester.h"

using namespace std;

IfstreamTester::IfstreamTester(void)
{}

IfstreamTester::~IfstreamTester(void)
{}

void IfstreamTester::doStuff()
{
    TestDataHelper helper = TestDataHelper("data.csv");
    // for every line in the file
    vector<double>* v;
    do
    {
        v = helper.getNextLine();
        cout << v << endl;
        delete v;
    } while(v != NULL);
}

IfstreamTester::TestDataHelper::TestDataHelper(std::string filename)
{
    datafile = new ifstream(filename.c_str());
    // read the header line
    string line;
    getline(*datafile, line);
}

vector<double>* IfstreamTester::TestDataHelper::getNextLine()
{
    if(!datafile->eof())
    {
        // readline
        string line = "";
        getline(*datafile, line);
        string delimiter = ",";
        vector<double>* res = new vector<double>();
        size_t pos = 0;
        // and tokenize line into vector of doubles
        while ((pos = line.find(delimiter)) != std::string::npos)
        {
            stringstream conv;            
            double token;
            conv << line.substr(0, pos);
            conv >> token;
            res->push_back(token);
            line.erase(0, pos + delimiter.length());
        }
        return res;
    }
    else
    {
        return NULL;
    }
}

IfstreamTester::TestDataHelper::~TestDataHelper()
{
    datafile->close();
    delete datafile;
}

和主要的:

#include "IfstreamTester.h"

void main()
{
    IfstreamTester s = IfstreamTester();
    s.doStuff();
}

有人知道为什么会这样吗?

编辑:我正在使用 Microsoft Visual Studio 2008 Express

最佳答案

你的编译器没有给你任何好处。应该是吐了,告诉你std::ifstream是不可复制的,因此也应隐式删除其包含父级 IfstreamTester 的默认复制构造函数。

我不知道您使用的是什么工具链,但 clang++ 3.3 和 g++ 4.7 都对此感到厌恶。由于复制省略假设,您的编译器显然允许它通过,然后未能在调试中实际省略拷贝。添加一个成员复制std::ifstream成员的复制构造函数,或者将main()声明为:

int main()
{
    IfstreamTester s;
    s.doStuff();
}

您代码中的非标准 void main() 声明让我(可能不正确地)推断您使用的是 MS 或 Borland 工具链。谁允许这样做(奇数 main() 和不可复制的 std::ifstream 成员被复制),就是不遵守规则。

关于c++ - 具有 ifstream 成员的内部类的构造函数返回无效的 fstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22195512/

相关文章:

c++ - 通过右值引用传递并使用 std::move() 返回?

C++ std::unordered_set SIGFPE 异常

c++ - 从文件 C++ 中读取一个单词的类

c++ - 从 end() 函数返回的迭代器获取 BST 的最后一个节点?

c++ - Windows Server 2012 服务中的 SOCKET 连接问题

c++ - 几个 ifstreams 访问冲突

C++ 访问冲突阅读为什么?

Delphi - 为什么我会收到此访问冲突? ADOQuery 参数有限制吗?

c++ - 写入文件后立即从文件中读取

C++从ifstream中拆分字符串并将它们放在单独的数组中