在基本的Java知识之后,我一直在努力学习C,并且我正在尝试实现一个链表。我在创建一个createList函数时遇到了麻烦 - 一个应该创建一个空列表的函数。虽然传递指针我有点奇怪的问题。这些只是代码的片段,我对节点/列表的定义位于书本CD给出的头文件中(所以这不是问题)
LList* createList(void){
LList list;
list.first = NULL;
printf("List from mk_list: \nfirst:%d\nlist address:%d\n",list.first,&list);
return &list;
} //This prints 0 and then the address of list
void print_list(LList *list){
printf("\nList from print_List\nFirst%d\nAddress:%d\n", list->first,list);
} //This prints some random non-null address for some reason, but also the
//SAME address as the list from createList. Why does list->first not print as 0?
int main(void)
{
LList*newList = createList();
printf("\nList from main:\nFirst:%d\nAddress:%d\n", newList->first,newList);
print_list(newList);
system("pause");
return 0;
} //Prints same exact thing as the printf in the createList.
答案 0 :(得分:3)
return &list;
list
驻留在堆栈上,其生命周期在函数返回时完成。因此,使用指向它的指针会调用未定义的行为。
在堆上创建对象。
答案 1 :(得分:1)
以下是您的问题:
LList* createList(void)
{
LList list;
...
return &list;
}
无论何时输入函数list
的代码,都会在堆栈上分配变量createList
。
每当调用此函数(或任何其他函数)时,堆栈处于不同的状态。
有时它满75%,有时只有24%(这只是一个比喻)。
您的局部变量是在堆栈的下一个空闲插槽中分配的,因此它在程序的整个生命周期内都没有常量地址,而只是在函数本身执行期间。
函数返回后的Shorty,可能会在同一地址中分配一些其他局部变量。
因此,返回此地址毫无意义,就像在代码中一样。
一个可选的解决方案是在LList newList
中声明main
,并将&newList
传递给createList
,而不是从该函数返回值:
void createList(LList* list)
{
list->first = NULL;
printf("List from mk_list: \nfirst:%d\nlist address:0x%X\n",list->first,list);
}
P.S。:您应该将此函数命名为initList
。