簡體   English   中英

在Visual C ++中的fgets()上接收訪問沖突錯誤

[英]Receiving access violation error on fgets() in visual c++

在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;
}

您沒有檢查malloc的返回值:

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

如果malloc失敗,則返回NULL

您正在嘗試分配大量內存,因此我將從此處開始。

如果j超過lines的元素數,則沒有任何保護:

while ( fgets(lines[j], 1440, fp) )
    j++; 

如果文件包含的行超過56000行,則將訪問數組之外​​的行。

因為這是C ++,所以您應該考慮使用ifstreamstd::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();
}

如果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' );
    }
}

簡單得多,它解決了您遇到的大多數問題。 (在實踐中,我可能會檢查文件是否單獨正確打開;如果您無法打開輸入,而不是將其視為空文件,通常會提示錯誤消息。)

當然,沒有理由在main使用new 只是:

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM