繁体   English   中英

编写一个 C 程序读取一行输入并使用 get_token() 将令牌存储在数组中但出现错误

[英]Writing a C program that reads a line of input and uses get_token() to store token in an array but getting errors

我正在编写一个程序,它读取一行输入,使用 get_token() 将该行所有标记的动态分配副本存储在字符串数组 arr 中,然后按标准 output 顺序打印这些标记。该程序不应存储空字符串和 arr 的限制将是 5 个字符串。

运行程序后,我得到“free(): invalid pointer”和“Abort (core dumped)”。 我已经尝试了所有我能想到的方法来修复这个程序,但我不知道为什么。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define NORMAL 0
#define NEWLINE 1
#define NULLBYTE 2

char *get_token(char **ptr, int *sts) {
  *sts = 4;
  char *tok = (char*) malloc(80);

  while (**ptr == ' ') {
    (*ptr)++;
  }

  if (**ptr != ' ') {
    int i = 0;
    while (**ptr != ' ' && **ptr != '\n' && **ptr != '\0') {
      tok[1] = **ptr;
      i++;
      // all chars are added
      (*ptr)++; // advance the pointer beyond the sequence
    }
    tok[i+1] = '\0';
  }

  if (**ptr == ' ') {
    *sts = NORMAL;
  } else if (**ptr == '\n') {
    *sts = NEWLINE;
  } else if (**ptr == '\0') {
    *sts = NULLBYTE;
  } else {
    *sts = 4;
  }

  if (*sts == 4) {
    return NULL;
  } else {
    return tok;
  }
}

int main() {
  
  char **arr = (char**) malloc(5);
  char *line = (char*) malloc(80); // getline argument 1
  char *line2 = line;
  size_t size = 80; // getline argument 2
  ssize_t ret;
  
  printf("Enter a line of input\n");

  if ((ret = getline(&line2, &size, stdin)) < 0) {
    perror("getline");
    return -1;
  } 
  
  char *token; 
  int sts;
  
  int i = 0;
  while (sts == NORMAL) {
    token = get_token(&line2, &sts);
    if (token != NULL) {
      arr[i] = token;
      i++;
    } else {
      printf("get_token() returned NULL\n");
    }
    
    if (i > 4) {
      printf("There are too many tokens\n");
      break;
    }
  }
  
  arr[i] = (char *) 0;
  i = 0;
  while (arr[i] != (char*) 0) {
    printf("Token: %s\n", arr[i]);
    //free(arr[i]);      //avoid
    i++;
  }

  free(line2); // problem with free(line2)
  free(arr);
  return 0;
}

我的 output 如下:

Enter a line of input
hi my name
Token:
Token:
Token:
free(): invalid pointer
Abort (core dumped)

您必须将指向动态分配的 memory 缓冲区的指针传递给free 该指针由malloc返回,存储在line2中并可能由getline修改。 至此,一切正常。

但是,您随后还修改了 function get_token中的line2 你不应该这样做,因为你必须记住line2的值,所以你可以在程序结束时将它传递给free 因此,您应该制作一个副本,然后您可以在 function get_token中修改它。

至少这些问题:

错误的分配大小。 也不需要投。

// char **arr = (char**) malloc(5);
char **arr = malloc(sizeof *arr * 5);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM