Reputation: 133
#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;
}
I have a few questions about the code I have written above. The general conceptual question being in main
I make a struct Node* tran
with this struct I call the newNode
function which takes in a struct Node*
. Now I put in tran
as a argument I do not pass the address of tran
. In which case wouldn't the function newNode
just create a copy of tran
's value and any manipulation in the function would be undone after the function call?
I notice this with a print statement at least that tran
's value does not change after the newNode
function call. What I'm trying to get at is how is my linked list expanding, and being kept tracked of? Does passing tran
's value as an argument work in this case because its pointing to the heap memory of the root's value initially, and then simply traversing the memory in heap, but not actually changing the contents of the memory?
If so then in order change the value of a node in the list I would have to pass &trans
as an argument, but if I'm just traversing the list to add a node at the end I can pass tran
as an argument?
My other question is I do not believe my freeList(struct Node* a)
function is working correctly. As when I free root
and then print it, it prints a garbage value for me when instead it should print "list is empty" or is it printing garbage cause its accessing memory I do not own?
Lastly, someone on here criticized my code for being "end user application code." I am still new to coding, and I was unsure if the code above is poorly formatted or what it means to be end user application code. I would be much appreciated if someone explained how I could avoid writing "end user application code."
Upvotes: 0
Views: 2666
Reputation: 53006
You are not passing trans
by value, you are passing a pointer to struct of Node
, so a copy will never be made.
You say
I do not pass the address of tran
and that's absolutely wrong, what you are passing is in fact exactly that.
The value doesn't change because you are not modifying the pointer, after each call to newNode
the trans
pointer points exactly to the same address it did before the call, so no change in the value should be observed.
When you call newNode
a new node is appended to the tail of the list, so if you actually traverse the list you would see all the values, the following code will print the values
struct Node *node;
for (node = root ; node != NULL ; node = node->next)
printf("value %d @ %p\n", node->val, node);
there you should see the address of each node, and it's value
free
is not meant to 0
the memory, instead you free
it, to the operating system, it's like you give up ownership of the memory at that address, if there was an obligation to 0
the memory, there would be a huge performance hit due to that.
If you want to make the list, empty
according to your code, you should do this exactly after calling freeList()
root = NULL;
remark: your freeList
function had a free(current)
at the end which double frees the last node, so I removed it, also fixed some style stuff, and made the printList()
function much more readable
#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)
{
struct Node *node;
if (head == NULL)
printf("empty list\n");
for (node = head ; node != NULL ; node = node->next)
printf("list is: %d\n", node->data);
}
int removeLastNode(struct Node* trans)
{
int val = -1;
/* return -1 if its a empty list */
struct Node *node;
struct Node *last;
if (trans == NULL)
return -1;
/*
* 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!
*/
node = trans;
last = node->next;
while (last->next != NULL)
{
node = node->next;
last = node->next;
}
trans = node;
node = node->next;
/* at end of the list? */
val = node->data;
/* free the heap */
free(node);
/* 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 != NULL)
{
temp=current;
/* going to the next one */
current=current->next;
/* freeing previous */
free(temp);
}
}
void addingHundred(struct Node* trans)
{
int i;
for (i=0 ; i < 100 ; i++)
newNode(trans, i);
}
int main()
{
struct Node* root;
int storage;
//create heap mem for root
root = malloc(sizeof(struct Node));
root->next=NULL;
root->data=10;
//adding a new node..
newNode(root, 8);
newNode(root, 12);
addingHundred(root);
//printing the list
printList(root);
//removing last node
storage = removeLastNode(root);
//returns the last nodes value
printf("value removed: %d\n", storage);
printList(root);
freeList(root);
root = NULL;
printList(root);
return 0;
}
I did this for your last comment, in your question body. Which I did not understand, but certainly you can improve your code formatting. Don't be afraid to use white space characters, the compiler ignores them anyway (except inside a string literal of course).
Upvotes: 2