连续调用同一个数组时出现奇怪的seg错误

时间:2014-02-18 03:02:48

标签: c arrays string fault

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

目前我在掌握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] = {“是”,“否”,“也许”},如果我调用argv [0],它会让我调用“是”,但任何其他调用(即使我再次调用argv [0])不工作并导致段错误。我可以调用数组中的任何元素,但是一旦我调用了一个元素,其余元素就会停止工作,从而导致段错误。

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

2 个答案:

答案 0 :(得分:1)

const char *results[numtokens+1];

此数组“results”是一个局部变量,只能在“makeargv”中使用。

你最好使用malloc:

results = malloc(numtokens+1)

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

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

答案 1 :(得分:1)

#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;
}