问题描述
我正在尝试将 .txt
文件中的多个参数读入 char**
。文本文件的每一行都包含一个参数。
我编写了以下代码,但不知何故遇到了段错误错误。我发现错误可能是这条线
argv[n_lines - 1] = const_cast<char*>(para.c_str());
我正在尝试将参数(c 字符串)分配给 char**
的插槽。不知怎么的,我被禁止进入该地点。
谁能指出我做错了什么以及如何纠正错误?
#include <iostream>
#include <fstream> // Use ifstream
char** file_to_argv(const char* filename) {
std::string line;
char** argv = NULL;
int n_lines = 0; // Number of parameters in total
std::ifstream file(filename); // read the entire file
std::string para; // parameter <-> each line in file
while (std::getline(file,para)) { // Keep reading in each parameter
argv = (char**)realloc(argv,sizeof(char*) * ++n_lines);
/* Check if enough memory is available */
if (argv = NULL)
exit(-1); // memory allocation fails
// Store parameter into argv array
argv[n_lines - 1] = const_cast<char*>(para.c_str());
}
/* Reallocate one extra slot for the last NULL so that argv is null
terminated,which is a good identifier when looping */
argv = (char**)realloc(argv,sizeof(char*) * (n_lines + 1));
return argv;
}
int main() {
char** argv = file_to_argv("parameters.txt");
int i = 0;
// print out all parameters line by line in the text file
while (argv[i] != NULL) {
printf("res[%d] = %s\n",i,argv[i]);
i++;
}
delete argv;
return 0;
}
解决方法
argv[n_lines - 1] = const_cast<char*>(para.c_str());
抛弃 const
-ness 已经是未定义的行为领域。所以,这已经被打破了。但这甚至不是主要问题。 c_str()
返回的指针归 std::string
所有,在对 std::string
进行any 后续修改后不再有效。但是您的代码接下来会做什么?
while (std::getline(file,para)) {
它立即将下一行读入 para
。先前返回的 c_str()
不再有效,从那时起取消引用它肯定会出现未定义的行为,并且可能会导致崩溃。
您的明显目标是构建一个与 C 兼容的 argv
样式数组。我过去使用的不违反任何规则的方法是构建一个
std::vector<std::vector<char>> argv;
然后让我的代码精心创建每个字符串,并明确 \0
终止它。然后为了构造最终的 C 样式 argv
,我只需抓住指向每个向量第一个字符的指针,并用它来构造一个
std::vector<char *> c_argv;
这不违反任何规则。无需在笨拙且容易出错的 malloc
或 realloc
调用上浪费时间。向量正确地为我管理了我的所有记忆。这就是向量的用途。