我有两个结构:HashTable,它包含指向WordNodes的指针表,每个WordNodes都包含指向List的指针,List是由ListNodes组成的链表。
我编写了一个函数来创建列表并将列表节点添加到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: %d\n",*((int*)dnode->occurrences),
      *((int*)dnode->id));
    printf("The dnode is %d\n", 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的使用位置-可能是您也没有复制该数据。

关于c - 分配给内存的修改结构在函数结束后不保留值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31905417/

10-11 23:03
查看更多