我有两个结构体:一个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
在哪里使用-这可能是你没有复制数据。