I'm using the following code to push a new node at the front of the linked list. I have some doubts regarding some concepts.
void push(struct node **head, int data)
{
// create a new node
struct node *new_node;
new_node = malloc(sizeof(struct node));
// add data
new_node->data = data;
// add node to front of list
new_node->next = *head;
*head = new_node;
}
When I assign the value of new_node
to *head
in *head = new_node
, and then return, does the pointer new_node
get destroyed, as it's an automatic variable?
Should the memory pointer by new_node
, assigned to it by the malloc
call still be legal to access after new_node
is destroyed, as it's on the heap, and was never de-allocated?
We're just using the new_node
as a placeholder to store an address to some memory, and after we're done with the assignments and stuff, we let it go. Then should it matter that new_node
is of type struct node
, for all pointers are just integers, and we're just using it to store a memory address. Where does the pointer type become relevant i.e. why do I have to declare the data type of the pointer to match the pointee's datatype?
Can I just declare all pointers as integers and then explicitly typecast them before using, to match the pointee's datatype?
for all pointers are just integers, and we're just using it to store a memory address.
No! Pointers are just address locations in memory and their size depends on the compiler and the architecture used. There's no guarantee by language that they are integers.
Where does the pointer type become relevant i.e. why do I have to declare the data type of the pointer to match the pointee's datatype?
Type safety. When you've a pointer to a character, it would be of type char*
, but casting it into an integer pointer and writing to it may lead to memory corruption. Let me show you an example
char ch = 'a';
char *cp = &ch;
int *ip = (int*) cp; // type safety lost since the pointer no longer refers to just one character
*ip = 1000; // memory to which 1000 is written to would span beyond a character's size
When *ip = 1000
is seen by the compiler, it has no way of warning you against this corruption since it believes that the underlying pointee is an integer; an integer can of course hold 1000
and thus compiles it fine; had it been *cp = 1000
this value would be implicitly converted into a value hold-able by a char
and thus no memory corruption by it. Also if you'd enabled warnings the compiler will be able to warn you of this narrowing implicit conversion. GCC spits warning: overflow in implicit constant conversion.
Can I just declare all pointers as integers and then explicitly typecast them before using, to match the pointee's datatype?
You certainly can, but don't, for the above reason. Read more about type safety.