微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

(Seg Fault) 使用 realloc 将文本文件逐行读入 char 双指针

如何解决(Seg Fault) 使用 realloc 将文本文件逐行读入 char 双指针

我正在尝试将 .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;

这不违反任何规则。无需在笨拙且容易出错的 mallocrealloc 调用上浪费时间。向量正确地为我管理了我的所有记忆。这就是向量的用途。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。