realloc():在 while 循环中使用 realloc 和 free 时,旧大小无效并中止(核心转储)

问题描述 投票:0回答:1

我正在开发一个使用链表实现的程序

typedef struct Node{
    char* word;
    int freq;
    struct Node *next;
}Node;

typedef struct {
    Node* head;

}LL;

并且有功能

void add_Node(LL* list, char* word, int freq){
  Node* newNode = (Node*)malloc(sizeof(Node));
  if(newNode == NULL){
    fprintf(stderr, "not able to create node\n");
    return;
  }
  
  newNode->word = strdup(word);
  if(newNode->word == NULL){
    fprintf(stderr, "can't allocate mem for word\n");
    free(newNode);
    return;
  }

  newNode -> freq = freq;
  newNode->next = NULL;

  if(list->head == NULL){
    list -> head = newNode;
  }
  else{
    Node* current = list->head;
    while(current->next != NULL){
      current = current->next;
    }
    current->next = newNode;
  }
  //return newNode;
}

void addFreq(LL* list, char* word){
  if(word == NULL){
    return;
  }

  Node* current = list->head;
  while(current != NULL){
    if(strcmp(current->word, word) == 0){
      current->freq++;
      return;
    }

    current = current->next;
  }
  add_Node(list, word, 1);
}

void destroyLL(LL* list){
  if(list == NULL){
    return;
  }

  Node* current = list->head;
  Node* next;
  while (current != NULL){
    next = current ->next;
    free(current->word);
    free(current);
    current = next;
  }

  list->head = NULL;
  free(list);
}  //clears the linked list so it can be used again

我的主要功能是嵌套 while 循环,该循环解析文件,每行包含一个单词,并将特定长度的单词存储在链接列表中,如下所示:

//assume all needed header files are included
int main(int argc, char *argv[]){
  LL* list = (LL*)malloc(sizeof(LL));
  //list->head = NULL;  
  
  //file meant to be parsed opened using fopen(/*name*/, "r"), nothing went wrong here
  input = fopen(argv[1], "r");  //file for the inputs
  
  char target[100];
  int length;
  int target_freq;
  
  while(fgets(target, sizeof(target), input) != NULL){ //gets inputs from input file
    
    if(sscanf(target, "%d %d", &length, &target_freq)==2){
      
      char word[100];
        while(fgets(word, sizeof(word), shake_txt) != NULL){ //parses the file of words
          if(strlen(word) == length+1){
          addFreq(list, word);   //adds 1 to the freq field of the node, if it does not exist, add the node
        }
      }
      sortLL(list);
      printf("%s", findWord(list, target_freq));
    }
    destroyLL(list);
    LL* list = (LL*)realloc(list,sizeof(LL));
  }
  //assume files are properly closed
}

运行程序后,仅运行 while 循环的第一次迭代,然后出现错误消息

Bard: malloc.c:2868: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed.
Aborted (core dumped)

有人知道如何修复吗?预先感谢。

我尝试将

destroyLL(list);
替换为
clearLL(list);
,但我收到了消息

realloc(): invalid old size
Aborted (core dumped

这里很清楚LL

void clearLL(LL* list){
  if(list == NULL || list -> head == NULL){
    return;
  }

  Node* current = list->head;
  Node* next;

  while(current != NULL){
    next = current->next;
    free(current->word);
    free(current);
    current = next; 
  }
  list->head = NULL;
}
c linked-list dynamic-memory-allocation
1个回答
0
投票

main
的顶部,您分配一个新列表但不初始化它:

LL* list = (LL*)malloc(sizeof(LL));
//list->head = NULL;  

由于未知的原因,您注释掉了初始化。因此,

head
的值是不确定的,并且您的程序具有未定义的行为。

稍后,当您尝试销毁列表并分配一个新列表时,您正在尝试

realloc
一个悬空指针。

destroyLL(list);
LL* list = (LL*)realloc(list,sizeof(LL));

除了它不是一个悬空指针——它是一个未初始化的指针,因为这里正在定义一个名为 list 的新

local
变量。

按照您的尝试将其更改为

malloc
仍然无法解决问题,因为属于较大范围
list
main
变量被此局部变量隐藏了。

您可以通过将这两行替换为:

来“清除”列表
clearLL(list);

无需重新分配

list


旁注:由于

clearLL
函数与
destroyLL
有很多共同点,因此您可以通过将
destroyLL
定义为:

来重用代码:
void destroyLL(LL* list){
    clearLL(list);
    free(list);
}
© www.soinside.com 2019 - 2024. All rights reserved.