Reputation: 978
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?
Upvotes: 2
Views: 153
Reputation: 32954
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.
Upvotes: 2
Reputation: 23135
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?
No, it does not. new_node will be valid as long as you free it. Since you do not have any handle to it once the function call is done, its memory is leaked. You cannot get it back.
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?
Same as first answer
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?
The pointer should be of the same type as the data it points to. It might need to know the size of the data it is pointing to manage the memory like free etc.
Can I just declare all pointers as integers and then explicitly typecast them
before using, to match the pointee's datatype?
You can use void pointers to transfer pointers across functions.
Upvotes: 1
Reputation: 98048
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?
What is destroyed is the pointer allocated on the stack, but the malloc'd memory remains (so head is valid), .
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?
It will be legal, and you can use it.
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?
Pointers are not integers, they may be larger than an integer and they are not signed. First of all you guarantee that the address will fit in the pointer. You can use a void pointer if you don't want to define a struct pointer but then you can not use it easily (without a cast) with the same pointer.
Can I just declare all pointers as integers and then explicitly typecast them before using, to match the pointee's datatype?
No, you can't. Use void pointers for this purpose.
Upvotes: 2
Reputation: 399949
new_node
as a pointer to a structure type, which has a field data
and another field next
. A void *
(or, worse, integer) wouldn't let you do that. The compiler needs the type information to make sense of an expression like new_node->data = data;
.Upvotes: 2