realloc,用于 C 中的字符串数组

realloc, for string array in C

当您想将可变大小的单词添加到字符串数组时,是否有使用 realloc 的正确方法?我遇到了分段错误。 请告诉我哪里出了问题

// This function puts every word found in a text file, to a String array, **words
char **concordance(char *textfilename, int *nwords){
    FILE * fp;
    char *fileName = strdup(textfilename);
    fp = fopen(fileName, "r");
    if(fp == NULL) {
        perror("fopen");
        exit(1);
    }
    char **words = malloc(sizeof(char));
    // char **words = NULL

    char line[BUFSIZ];
    while(fgets(line, sizeof(line), fp) != NULL){
        char *word = strdup(line);
        word = strtok(word, " ");
        do{
            words = realloc(words, (*nwords+1) * sizeof(char(*)));
            words[*nwords] = word;
        } while((word = strtok(NULL, " ")) != NULL);
    }
    return words;
}


int main(int argc, const char * argv[]) {
    int *nwords = malloc(sizeof(int));
    nwords = 0;
    concordance("test.txt", nwords);
}

当您初始化 nwords 的值时,您覆盖的是它的指针地址,而不是它的值。

此外,正如评论者所说,char **words = malloc(sizeof(char)); 行不正确。但是你总是重新分配变量 words 所以代码仍然按预期工作。为了使其超级安全,您应该将其更改为 char **words = malloc(sizeof(char*));

我使用 *nwords = 0; 行,现在它按预期工作了。

#define BUFSIZ 1000
#include<stdio.h>
// This function puts every word found in a text file, to a String array, **words
char **concordance(char *textfilename, int *nwords){
  FILE * fp;
  char *fileName = strdup(textfilename);
  fp = fopen(fileName, "r");
  if(fp == NULL) {
    perror("fopen");
    exit(1);
  }
  char **words = malloc(sizeof(char));
  // char **words = NULL

  char line[BUFSIZ];
  while(fgets(line, sizeof(line), fp) != NULL){
    char *word = strdup(line);
    word = strtok(word, " ");
    printf("word='%s'\n",word);
    do{
      *nwords=*nwords+1;
      printf("nwords=%d\n",*nwords);
      words = realloc(words, (*nwords+1) * sizeof(char(*)));
      words[*nwords] = word;
    } while((word = strtok(NULL, " ")) != NULL);
  }
  return words;
}


int main(int argc, const char * argv[]) {
  int *nwords = malloc(sizeof(int));
  *nwords = 0;
  concordance("test.txt", nwords);
}

您似乎以错误的方式将 nwords 初始化为 0。由于您已将其声明为指针,因此无法直接访问它。相反,您应该使用取消引用运算符 *

main 函数中进行以下更改

*nwords = 0; 而不是 nwords = 0;

nwords = 0nwords 指向的位置修改为地址为 0 的位置,您无权访问且无法分配。

警告:

  1. 最好不要对同一个指针执行realloc,如果realloc失败会使指向位置NULL,导致之前存在的数据丢失.相反,正如@David 建议的那样,您可以将临时变量用于 realloc 内存,然后检查它是否不是 NULL 然后将其内容分配给 words 指针。
    //your code
    char *tmp = realloc(words, /* new size*/);
    if(tmp != NULL)
        words = tmp;
    // your code
  1. 在使用 realloc 时,您通常使用它来分配数据块,而不是单个位置。