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

时间:2015-08-09 14:43:35

标签: c pointers struct

我有几个结构:一个HashTable,它包含一个指向WordNodes的指针表,每个WordNode包含一个指向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程序员的初学者错误,但我似乎无法弄清楚我在哪里弄错了。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

代码中有一组问题:

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的使用位置 - 可能是您没有复制该数据。