在内存中分配的修改结构体在函数结束后不再保留值



我有两个结构体:一个HashTable,它包含一个指向WordNode的指针表,每个WordNode包含一个指向List的指针,List是一个由listnode组成的链表。

我写了一个函数来创建列表并将列表节点添加到WordNode:

int addWord(char* word, HashTable* hash_table, int id)
{
  WordNode* current = calloc(1, sizeof(WordNode));
  current = hash_table->table[hash];
  // ...
  if(current->docs == NULL){
    // Create a new list, and initialize it
    List* list = calloc(1, sizeof(List));
    list->head = NULL;
    list->tail = NULL;
    int occur = 1;
    ListNode* list_node = AddNode(list); // Create the first node in the list
    current->docs = list;                // Link the WordNode to the list
    // Fill in relevant details of ListNode
    list_node->id= &id;    
    list_node->occurrences = &occur;
    list_node->next = NULL;

这是我的函数,但由于它一直给我带来麻烦,我在里面添加了几行来测试它:

    printf("Testing:n");
    WordNode* wnode = calloc(1, sizeof(WordNode));
    wnode = hash_table->table[hash];
    List* my_list = calloc(1, sizeof(List));
    my_list = wnode->docs;
    ListNode* dnode = calloc(1, sizeof(ListNode));
    dnode = my_list->head;
    printf("Results: ocurrences: %d, id: %dn",*((int*)dnode->occurrences),
      *((int*)dnode->id));
    printf("The dnode is %dn", doc_node);
}

在main中调用时,函数中的测试代码产生预期的输出:

Results: ocurrences: 1, id: 15
The dnode is 13867424

然而,在main中紧接着函数调用的行中进行同样的测试会产生一个奇怪的输出,尽管指针似乎指向相同的地址。

Results: ocurrences: 0, id: 54
The dnode is 13867424

可能与向列表添加新节点的函数相关的代码:

ListNode* AddNode(List * list)
{
  ListNode* node = calloc(1, sizeof(ListNode));
  node->next = NULL;
  if(list->tail == NULL){
      list->head = node;
      list->tail = node;
  }
  else{
      list->tail->next = node;
      list->tail = node;
  }
  return node;
}
我似乎不知道我做错了什么。在我看来,我以某种方式处理结构体作为局部变量,即使我为它们分配内存,这让我认为它们不应该在函数完成后改变。这可能是c程序员初学者的错误,但我似乎不知道我在哪里犯了这个错误。

代码中有一组问题:

int addWord(char* word, HashTable* hash_table, int id)
{
    …omitted…
    int occur = 1;
    ListNode* list_node = AddNode(list); // Create the first node in the list
    current->docs = list;                // Link the WordNode to the list
    // Fill in relevant details of ListNode
    list_node->id= &id;    
    list_node->occurrences = &occur;

在结构体中存储了一个指向形参的指针和一个指向局部变量的指针。在函数返回后解引用其中任何一个都是未定义的行为。这些占用的空间可以被编译器在任何时候出于任何目的重用;它们可能会完全失效(但也可能不会)。

为什么在你的结构体中有指向这两个项目的指针?当然,结构应该只包含几个int成员,而不是int *成员!

如果你的代码编译时有警告,不要提交给SO;首先修复警告。或寻求有关如何解决编译器警告的帮助。它们都很重要。在您职业生涯的这个阶段,请记住编译器比您更了解C语言。如果它对代码中的某些内容发出警告,那么编译器的担心可能是正确的,而代码可能在某些方面是不正确的。

你的代码没有显示word在哪里使用-这可能是你没有复制数据。

最新更新