【问题标题】:Weird seg faults on consecutive calls to the same array连续调用同一数组时出现奇怪的段错误
【发布时间】:2014-02-18 03:02:47
【问题描述】:

我非常努力地寻找解决方案,但我想不出足够好的关键字。

目前我很难理解 makeargv 背后的概念以及它与三指针的用法(我不知道 ***foo 是什么意思,它似乎不像 **foo 或 * 那样简单的概念富)。所以我自己做了:

const char **makeargv(char *string, int *numargs) {
  string = string + strspn(string, delims);
  char *copy = malloc(strlen(string) + 1);
  int i;
  strcpy(copy, string);

  int numtokens;
  if (strtok(copy, delims) != NULL) {
    for (numtokens = 1; strtok(NULL, delims) != NULL; numtokens++) {}
  }

  strcpy(copy, string);

  const char *results[numtokens+1];

  results[0] = strtok(copy, delims);

  for (i = 1; i < numtokens; i++) {
    results[i] = strtok(NULL, delims);
  }

  results[numtokens+1] = NULL;
  *numargs = numtokens;
  return results;
}

这是它断裂的部分:

void parse_file(char* filename) {
    char* line = malloc(160*sizeof(char));
    FILE* fp = file_open(filename);
    int i = 0;
    int numargs = 0;
    int *pointer = &numargs;


    while((line = file_getline(line, fp)) != NULL) {
      if (strlen(line) == 1){
        continue;
      }

  const char **args = makeargv(line, pointer);

  printf("%s\n", args[0]);
  printf("%s\n", args[1]);
      /* This prints out args[0], but then args[1] causes a seg fault. Even if I replace
         the args[1] with another args[0] it still causes a seg fault */

}
fclose(fp);
free(line);
}

我有一个有效的字符串数组。但是,当我尝试打印出数组中的字符串时,我只能打印我选择的 1 个,然后它会为任何后续调用分段错误。假设我的字符串数组是 argv[3] = {"Yes", "no", "maybe"},如果我调用 argv[0],它会让我调用“Yes”,但任何其他调用(即使我再次调用 argv[0])不起作用并导致段错误。我可以调用数组中的任何元素,但是一旦我调用了一个,其余的就会停止工作,从而导致段错误。

请帮忙? D:这是在 C 中。

【问题讨论】:

  • 您应该创建a Minimal, Complete, Tested and Readable example,而不是描述您遇到的情况。
  • 很抱歉我当时正在转机,因为我在使用的计算机上由于某些奇怪的原因而遇到复制和粘贴问题。我已经修好了,你现在有机会看看吗? :D

标签: c arrays string fault


【解决方案1】:
const char *results[numtokens+1];

这个数组“results”是一个局部变量,它只在“makeargv”内部可用。

你最好使用 malloc:

results = malloc(numtokens+1)

而且我相信您的代码中存在内存泄漏。 您将无法为“char *copy”释放内存

char *copy = malloc(strlen(string) + 1);

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char **makeargv(char *string, int *numargs) {
        static const char *delims = " \t\n";
        string = string + strspn(string, delims);
        char *copy = malloc(strlen(string) + 1), *p = copy;
        strcpy(copy, string);
    
        int numtokens;
        for (numtokens = 0; strtok(p, delims); ++numtokens, p = NULL);
    
        char **results = malloc(sizeof(char*)*(numtokens+1));
        strcpy(copy, string);
    
        int i;
        p = copy;
        for (i = 0; i < numtokens; ++i, p = NULL)
            results[i] = strtok(p, delims);
        results[i] = NULL;
        *numargs = numtokens;
        return results;
    }
    
    FILE *file_open(char *filename){
        FILE *fp = fopen(filename, "r");
        if(!fp){
            perror("file_open");
            exit(1);
        }
        return fp;
    }
    
    void parse_file(char* filename) {
        char* line = malloc(160*sizeof(char));
        FILE* fp = file_open(filename);
        int i = 0, numargs = 0;
    
        while(fgets(line, 160, fp)){
            if (*line == '\n')
                continue;
    
            char **args = makeargv(line, &numargs);
            for(i = 0;i<numargs;++i)
                printf("%s\n", args[i]);
            printf("\n");
    
            if(args[0])
                free(args[0]);
            free(args);
        }
        fclose(fp);
        free(line);
    }
    
    int main(int argc, char *argv[]){
        parse_file(argv[1]);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-03
      • 1970-01-01
      • 2014-12-09
      • 2021-11-26
      • 1970-01-01
      相关资源
      最近更新 更多