在我的程序中,我可能需要加载一个大文件,但并非总是如此。所以我定义了:
char** largefilecontents;
string fileName="large.txt";
当我需要加载文件时,程序调用这个函数:
bool isitok=LoadLargeFile(fileName,largefilecontents);
函数是:
bool LoadLargeFile(string &filename, char ** &lines)
{
if (lines) delete [] lines;
ifstream largeFile;
#ifdef LINUX
largeFile.open(filename.c_str());
#endif
#ifdef WINDOWS
largeFile.open(filename.c_str(),ios::binary);
#endif
if (!largeFile.is_open()) return false;
lines=new char *[10000];
if (!lines) return false;
largeFile.clear();
largeFile.seekg(ios::beg);
for (int i=0; i>-1; i++)
{
string line="";
getline(largeFile,line);
if (largeFile.tellg()==-1) break; //when end of file is reached, tellg returns -1
lines[i]=new char[line.length()];
lines[i]=const_cast<char*>(line.c_str());
cout << lines[i] << endl; //debug output
}
return true;
}
当我查看此函数的调试输出“cout << lines[i] << endl;”时,一切正常。但是当我像这样在主程序中检查它时,一切都搞砸了:
for (i=0; i<10000; i++)
cout << largefilecontents[i] << endl;
所以在函数 LoadLargeFile()
中,结果很好,但是没有 LoadLargeFile()
,结果就乱七八糟了。我的猜测是函数的 char ** &lines
部分不正确,但我不知道这应该是什么。
有人可以帮助我吗?提前致谢!
最佳答案
问题出在您使用 line.c_str
的地方。您首先使用 lines[i]=new char[line.length()];
为新字符串分配内存,然后覆盖 line[i]
中的指针> 使用指向局部变量 line
中的 c_str 的指针。当 line
超出范围时,此 c_str
将被销毁。您需要做的是使用 strcpy
而不是简单的指针赋值。
尝试以下操作
lines[i]=new char[line.length()+1]; //Thanks @Claptrap for the catch
strncpy(lines[i], line.c_str(), line.length()+1); //Note, strcpy is not considered safe.
//Use strncpy
如果您想严格遵守 C++ 方式,那么我建议您使用 @christian-hackl 的建议
std::vector<std::string> largefilecontents; //Since in your case 10000 is fixed
...
bool LoadLargeFile(string &filename, std::vector<std::string> &lines)
{
...
//lines=new char *[10000];
//if (!lines) return false;
lines.resize(10000); //Since in your case 10000 is fixed
...
for...
if(i >= lines.size()) break; //safety net in case more than 10000 lines
lines[i]="";
getline(largeFile,lines[i]);
if (largeFile.tellg()==-1) break; //when end of file is reached, tellg returns -1
//lines[i]=new char[line.length()];
//lines[i]=const_cast<char*>(line.c_str());
旁注:数组 v/s vector
数组是原始的 C++ 数据类型,而 vector 是类,是标准模板库的一部分。这意味着理论上 vector 比数组慢。但在实践中,速度的下降可以忽略不计。 vector 以可忽略的成本提供了两个巨大的好处
- 内存管理。您不必删除内存,一旦 vector 对象超出范围,分配的内存就会被删除。在您的示例中,您似乎不一定需要它,因为在一般情况下您的数组永远不会被销毁
- 灵 active 。对于数组,您必须预先知道预期的大小。而 vector 根据需要扩展。同样,您不一定需要它,因为正如您所说, vector 大小是固定的。
有两个与 vector 相关的成本
- 性能: vector 可能比对数组的操作稍慢,但由于大多数(如果不是全部)操作被描述为内联函数,编译器开始优化它,并使它或多或少成为像数组一样高效。对于固定大小的 vector 尤其如此。
- 内存:Vector 是一个内部使用数组的容器,这意味着 Vector 对象会有轻微的内存开销。但是将其与您可能会节省的费用进行比较,但不分配一个巨大的数组,而是逐渐扩展 vector 。仅当您创建大量小 vector 时, vector 的内存开销才可能是一个问题。在您的情况下,这种开销微不足道。
引用资料:
关于c++ - 将 char 数组的数组传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23898593/