我在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;
}
答案 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;
}