[英]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 ++,所以您應該考慮使用ifstream
, 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();
}
如果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.