【问题标题】:Why does my C program crash when i add any statement to the main function?当我向主函数添加任何语句时,为什么我的 C 程序会崩溃?
【发布时间】:2020-07-02 13:44:48
【问题描述】:

我对 C 语言相当陌生 - 我编写了一个程序来读取文本文件,并通过几个函数使用 malloc()realloc() 处理文本并格式化输出。目前我的main() 中只有以下内容:

1.初始化结构体

  line_arr.max_size = 0;
  line_arr.num_lines = 0;
  line_arr.line = NULL;

  Word_Array word_arr;
  word_arr.max_size_ = 0;
  word_arr.num_words = 0;
  word_arr.word = NULL;

  Word_Array ex_words;
  ex_words.max_size_ = 0;
  ex_words.num_words = 0;
  ex_words.word = NULL; 

Line_Array.lineWord_Array.word 分别是结构体 LineWord 的指针。 Line 和 Word 是包含一个 char 数组和一个 int 的结构,用于跟踪该行的行号或单词出现的位置。

2。调用处理输入文本文件的函数

  get_lines(&line_arr, argv[1]);
  get_words(&line_arr, &word_arr);
  sort_keywords(&word_arr);

我所有的函数都返回void

所有的输出和格式化都发生在函数和我拥有的任何空间malloc'd 我随后释放而没有任何错误。该程序会产生所需的输出,但是,如果我将任何语句添加到 main() 甚至是打印语句,我会收到 bus10 错误或 segmentation fault 11 错误。

我已经尝试过 gdb,但我之前没有使用过它,而且当我尝试运行程序时似乎 gdb 挂起并冻结。

我想知道是否有人知道为什么会这样? / 是否有一些关于 C 或 malloc() 的基本逻辑我不理解?

感谢您的专业知识!

编辑 结构:

typedef struct Line Line;
struct Line{
  char line[MAX_LINE_LEN];
};

typedef struct Word{
  char word[MAX_WORD_LEN];
  int line_number;
}Word;

typedef struct Word_Array{
  //will point to the base in memory where the list of words begins.
  Word *word;
  int max_size_;
  int num_words;
}Word_Array;

typedef struct Line_Array{
  //line is a variable that stores an address of a line object.
    Line *line;
    int max_size;
    int num_lines;
}Line_Array;

get_lines():

void get_lines(Line_Array *la, char const *filename){
  Line *line_ptr;
  char *buffer;
  size_t buffer_len;

  FILE *fp = fopen(filename, "r");
  if(fp == NULL){
    printf("Can't read file. \n");
    exit(1);
  }

  while (getline(&buffer, &buffer_len, fp) > 0) {
    buffer[strlen(buffer)-1] = '\0';
    if (la->line == NULL) {
      la->line = (Line *) malloc(sizeof(Line));
      if (la->line == NULL) {
        exit(1);
      }
      la->max_size = 1;
      la->num_lines = 0;
    }

    else if (la->num_lines >= la->max_size) {
      line_ptr = (Line *) realloc(la->line, (2*la->max_size) * sizeof(Line));
      if (line_ptr == NULL) {
        exit(1);
      }

      la->max_size *= 2;
      la->line = line_ptr;

    }

    strncpy(la->line[la->num_lines].line, buffer, MAX_LINE_LEN);
    la->num_lines++;
  }
  fclose(fp);
}

我没有释放此方法中的内存,因为我稍后会使用它,但即使没有运行其他函数,也存在相同的问题,如果我在调用 get_lines 之前或之后向 main 添加一些东西,我接收总线 10 错误作为我唯一的输出。但是,如果我只调用 get_lines() 和其他函数,程序会产生正确的输出。

【问题讨论】:

  • 需要查看完整的代码,或者至少是一个有代表性的示例,包括结构定义。
  • 听起来你在某处出现了内存错误,但如果没有看到更完整的示例,就不可能找到它。
  • 您的内存访问无效。尝试使用valgrind 运行它并检查无效的读取和/或写入。
  • 您将未初始化的char *buffer 的地址传递给函数getline。局部变量必须显式初始化。
  • 我恢复了您上次的编辑:您不应该这样做,它使 cmets 和答案无关紧要。您可以通过单击分数下方的灰色复选标记来接受答案。如果您坚持要删除代码,请先接受答案并删除问题。

标签: c debugging malloc


【解决方案1】:

至少一个问题:

变量需要在getline() 使用前进行初始化。 @Weather Vane

  //char *buffer;
  //size_t buffer_len;
  char *buffer = NULL;
  size_t buffer_len = 0;

注意事项:

while (getline(... 之后,代码应该使用 free(buffer); 释放

strncpy(la->line[la->num_lines].line, buffer, MAX_LINE_LEN); 不保证la->line[la->num_lines].line 是一个字符串Why is strncpy insecure?

【讨论】:

  • 我不确定while 循环的后续迭代会发生什么,没有充分研究代码以查看是否需要分配 另一个 缓冲区或其他什么。
  • @WeatherVane 同意,添加了另一个注释。
  • 哇——成功了!添加了空闲(缓冲区)并初始化了这些变量。感谢大家的帮助!
猜你喜欢
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
相关资源
最近更新 更多