我有几个结构:一个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程序员的初学者错误,但我似乎无法弄清楚我在哪里弄错了。任何帮助将不胜感激。
答案 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
的使用位置 - 可能是您没有复制该数据。