【发布时间】:2015-03-08 09:13:33
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
//why does this work with pointers thought they made a copy?
//am i freeing memory correctly and well?
//Something wrong with freeing
struct Node{
struct Node* next;
int data;
};
void newNode(struct Node* trans, int val)
{
if(trans!=NULL)
{
while(trans->next!=NULL)
{
trans=trans->next;
}
//next is null create heap memory
trans->next=malloc(sizeof(struct Node));
//checking to see if memory is created
if(trans->next==NULL)
{
printf("This has failed");
}
//put in data
trans->next->data=val;
//next is null
trans->next->next=NULL;
}
}
void printList(struct Node* head)
{
if(head!=NULL)
{
struct Node* current;
current=head;
while(current->next!=NULL)
{
//print that current nodes data
printf("list is: %d\n",current->data);
current=current->next;
}
printf("last element is: %d\n",current->data);
}
else
{
printf("list is empty!");
}
}
int removeLastNode(struct Node* trans)
{
//return -1 if its a empty list
int val=-1;
if(trans!=NULL)
{
/*have to access trans->next->next cause you are freeing trans->next->next and getting its val
then you want to set tran->next to NULL!
*/
while(trans->next->next!=NULL)
{
trans=trans->next;
}
//at end of the list?
val=trans->next->data;
//free the heap
free(trans->next);
//next points to null
trans->next=NULL;
}
return val;
}
//LOOK AT ME!
void freeList(struct Node* root)
{
struct Node* temp;
struct Node* current;
current=root;
while(current->next!=NULL)
{
temp=current;
//going to the next one
current=current->next;
//freeing previous
free(temp);
}
//Am I really freeing the last one?
free(current);
root->next=NULL;
root=NULL;
}
void addingHundred(struct Node* trans)
{
int i;
for(i=0;i<100;i++)
{
newNode(trans,i);
}
}
int main()
{
struct Node* root;
//create heap mem for root
root=malloc(sizeof(struct Node));
root->next=NULL;
root->data=10;
//traversal pointer
struct Node* trans;
//setting to point to root
trans=root;
//adding a new node..
newNode(trans,8);
printf("value of trans after function call: %p\n",trans);
newNode(trans,12);
//value does not change
printf("value of trans after function call: %p\n",trans);
addingHundred(trans);
//printing the list
printList(root);
int storage;
//removing last node
storage=removeLastNode(trans);
//returns the last nodes value
printf("value removed: %d\n",storage);
printList(root);
freeList(root);
printList(root);
return 0;
}
我对上面编写的代码有几个问题。一般概念问题在main 中,我用这个结构创建了一个struct Node* tran,我调用了newNode 函数,它接收一个结构Node*。现在我输入tran 作为参数,我没有传递tran 的地址。在这种情况下,函数newNode 不会创建tran 值的副本,并且函数中的任何操作都将在函数调用后撤消?
我在 print 语句中注意到这一点,至少 tran 的值在 newNode 函数调用后不会改变。我想要了解的是我的链接列表如何扩展并被跟踪?在这种情况下是否将tran 的值作为参数传递,因为它最初指向根值的堆内存,然后简单地遍历堆中的内存,但实际上并没有改变内存的内容?
如果是这样,那么为了更改列表中节点的值,我必须将 &trans 作为参数传递,但如果我只是遍历列表以在末尾添加一个节点,我可以传递 @987654334 @ 作为参数?
我的另一个问题是我不相信我的freeList(struct Node* a) 函数工作正常。当我释放root 然后打印它时,它会为我打印一个垃圾值,而它应该打印“列表为空”还是打印垃圾会导致它访问我不拥有的内存?
最后,这里有人批评我的代码是“最终用户应用程序代码”。我仍然是编码新手,我不确定上面的代码是否格式不正确,或者最终用户应用程序代码意味着什么。如果有人解释我如何避免编写“最终用户应用程序代码”,我将不胜感激。
【问题讨论】:
-
这是个大问题。
-
不解释不知道怎么问清楚。
-
代码应始终检查 malloc(和系列)的返回值,以确保操作成功
-
指针的副本仍然指向同一个地方。所以指针可以作为参数传递并且仍然可以正常工作。 IE。可以修改指针指向的地方。但是,它需要是指向指针的指针才能改变指针指向的位置
-
@user3629249 谢谢,这是我需要澄清的事情之一。为了确保遍历此处有效,因为我们没有修改指针最后指向的位置,而是使用它来临时转到列表的末尾?
标签: c function pointers struct linked-list