在visual c ++中接收fgets()上的访问冲突错误

时间:2012-03-19 09:17:37

标签: c++ visual-c++ file-io

我在Visual Studio上运行以下代码时出现访问冲突错误。也许我正在尝试读取一些我没有分配的指针位置或者什么,但我似乎无法找到问题的确切位置。需要一些帮助。

#include <iostream>

class fileReader
{
public:
    FILE *fp;
    char** lines;
    fileReader()
    {
        fp = NULL;
    }
    fileReader(char* path)
    {
        int j=0;
        fp = fopen(path,"r");
        if (fp == NULL) 
            return;
        else 
        {
            lines = (char**) malloc(sizeof(char *)*56000);
            for (int i=0; i<56000; i++)
                lines[i] = (char*)malloc(sizeof(char)*1440);
            while ( fgets(lines[j], 1440, fp) )
                j++;
            fclose(fp);
        }
    }
};

int main(int argv, char** argc)
{
    char* path = "D:\\testfile.txt";
    fileReader *p = new fileReader(path);
    for (int i=0; i<2; i++)
        std::cout<<p->lines[i];
    return 0;
}

3 个答案:

答案 0 :(得分:2)

您没有检查malloc的返回值:

 lines = (char**) malloc(sizeof(char *)*56000);
 for (int i=0; i<56000; i++)
     lines[i] = (char*)malloc(sizeof(char)*1440);

如果malloc失败,则返回NULL

你正试图分配相当多的内存,所以我从那里开始。

答案 1 :(得分:2)

j

lines超出元素数量的while ( fgets(lines[j], 1440, fp) ) j++; 没有任何保护
56000

如果文件包含更多ifstream行,那么这将超出数组的范围。

由于这是C ++,您应该考虑使用std::getline()std::vector<std::string>std::vector<std::string>来读取文件。 std::vector<std::string> lines; std::ifstream in("D:\\testfile.txt"); if (in.is_open()) { std::string line; while (std::getline(in, line)) { lines.push_back(line); } in.close(); } 将为您管理内存分配:

{{1}}

答案 2 :(得分:1)

如果fopen失败会怎样?我看到一些未初始化的指针 在这种情况下漂浮。在不太可能的情况下malloc 失败了,你将会有一些空指针,这不应该是 解引用。而且你不能确保至少有两行 实际上在main中执行循环之前已阅读;如果没有,你就是 试图输出未初始化的数据。更不用说事实了 你永远不会释放你分配的记忆。

(FWIW:使用您的策略,j应公开,但fp可以是本地的 到FileReader::FileReader。)

几乎完全等同于使用:

std::vector<std::vector<char> > lines;
//  ...
FileReader( char const* path )
    : lines( 56000, std::vector<char>( 1440 ) ) 
{
    //  ...
}

唯一的区别是对fgets的调用,这必须是 fgets( &lines[j][0], lines[j].size(), fp )

我可能更喜欢使用初始化的std::vector<std::string> 空,然后对每一行读回:

FileReader( char const* path )
{
    std::ifstream input( path );
    std::string line;
    while ( std::getline( input, line ) ) {
        lines.push_back( line + '\n' );
    }
}

更简单,更简单,它解决了您遇到的大多数问题。 (实际上,我可能会检查文件是否正确打开 分别;如果你不能给出错误信息通常很好 打开输入,而不是将其视为空文件。)

当然,我没有理由在new中使用main。只是:

int
main()
{
    FileReader file( "D:/testfile.txt" );
    for ( size_t i = 0; i != file.lines.size(); ++ i ) {
        std::cout << file.lines[i];
    }
    return std::cout.flush() ? EXIT_SUCCESS : EXIT_FAILURE;
}