Pointers are a really tricky thing in C. For a lot of people is hard to understand it, so for a good understanding I wrote following code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int *p; // pointer -> will be dynamic allocated
int *a; // array -> will be dynamic allocated
// print before allocate memory (1)
printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
printf("&a: %p\ta: %p\t*a: %d\n", &a, a, *a);
printf("\n");
// allocate memory (2)
p = (int *)malloc(sizeof(int));
a = (int *)malloc(sizeof(int) * 10);
// print after allocate, but before give a value to poinetrs (3)
printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
printf("&a: %p\ta: %p\t*a: %d\n", &a, a, *a);
printf("\n");
// give a value to poinetrs (4)
*p = 1;
for (int i = 0; i < 10; i++) { a[i] = i; }
// print after we gave a value to pointers (5)
printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
printf("&a: %p\ta: %p\t*a: ", &a, a);
// because a is an array we must use a loop for print
for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
printf("\n");
printf("\n");
// free pointers (6)
free(p);
free(a);
// print pointers after free (7)
printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
printf("&a: %p\ta: %p\t*a: ", &a, a);
// because a is an array we must use a loop for print
for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
printf("\n");
printf("\n");
// try to change values after free (8)
*p = 12;
for (int i = 0; i < 10; i++) { a[i] = 3; }
// print after (8)
printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
printf("&a: %p\ta: %p\t*a: ", &a, a);
// because a is an array we must use a loop for print
for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
printf("\n");
printf("\n");
return 0;
}
Output:
&p: 0xbfe5db64 p: 0xbfe5dc24 *p: -1075452506
&a: 0xbfe5db68 a: 0xbfe5dc2c *a: -1075452502
&p: 0xbfe5db64 p: 0x8716008 *p: 0
&a: 0xbfe5db68 a: 0x8716018 *a: 0
&p: 0xbfe5db64 p: 0x8716008 *p: 1
&a: 0xbfe5db68 a: 0x8716018 *a: 0 1 2 3 4 5 6 7 8 9
&p: 0xbfe5db64 p: 0x8716008 *p: 0
&a: 0xbfe5db68 a: 0x8716018 *a: 0 1 2 3 4 5 6 7 8 9
&p: 0xbfe5db64 p: 0x8716008 *p: 12
&a: 0xbfe5db68 a: 0x8716018 *a: 3 3 3 3 3 3 3 3 3 3
Now, questions and observations:
When I print pointers before give memory for it, why pointer have a random value and a random address to point to it and why it isn't NULL?
After we use malloc, we can see the address where pointer points to changed and its value is NULL, so what malloc really does?
After we give a value to it and print it, we free it and print it again, but values and address are same as behind for array, but not for the integer, why? So what free really does?
After we freed space, we can continue to change values of array and integer, why is this possible after free space? We don't need to reuse malloc?
If successful, malloc returns a pointer to the newly allocated block of memory. If not enough space exists for the new block, it returns NULL. The contents of the block are left unchanged. If the argument size == 0, malloc returns NULL.
How do malloc () and free () work in C/C++? The function malloc () is used to allocate the requested size of bytes and it returns a pointer to the first byte of allocated memory. It returns null pointer, if it fails.
If the argument size == 0, malloc returns NULL. How can I use malloc () and free () functions? The free () function is a Dynamic Memory Allocation function that frees allocated block. Free () deallocates a memory block allocated by a previous call to calloc , malloc, or realloc.
The function free () is used to deallocate the allocated memory by malloc (). It does not change the value of the pointer which means it still points to the same memory location. pointer_name − Any name given to the pointer.
Because the language specification says so. The value of the pointer (i.e. the address it points to) is indeterminate. It can point anywhere, just like an int
could hold any value. Reading those values, (as you do with *p
and *a
in the first printf
s) is actually undefined behaviour.
If you mean the data it points to is 0
, that is by chance. The memory allocated does not have to be zeroed out. For example, it could be part of a block previously allocated with malloc
and then free
d (free
doesn't zero out the memory, see point 3. below.)
That is also by chance. When you free
the memory, it is not zeroed out, and it does not have to be used immediately. It can keep storing old values until it is used for something else (for instance, by another allocation)
That is also undefined behaviour. You are writing to memory you no longer own. Anything can happen. The program could have crashed. By chance, it seems like you can successfully write to the array, probable because the memory is still not used by anything else that would cause a more apparent run time error.
1.When I print pointers before give memory for it, why pointer have a random value and a random address to point to it and why it isn't NULL?
You didn't make the pointer NULL. you are just declaring it. After declaring the pointer, it may have any value.
To make NULL-
int *p = NULL;
int *a = NULL;
2.After we use malloc, we can see the address where pointer points to changed and its value is NULL, so what malloc really does?
Man Page says-
void *malloc(size_t size);
The malloc()
function allocates size
bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc()
returns either NULL, or a unique pointer value that can later be successfully passed to free()
.
If your allocated memory have 0 means that is by a chance only! The memory allocated by malloc
doesn't freed out. But calloc
does!
3.After we give a value to it and print it, we free it and print it again, but values and address are same as behind for array, but not for the integer, why? So what free really does?
free
does not mean that it will actually delete the memory! It will inform to the OS that I don't want this memory any more, use it for some other process!
You can certainly continue to use memory a after calling free(...)
and nothing will stop you. However the results will be completely undefined and unpredictable. It works by luck only. This is a common programming error called "use after free" which works in many programs for literally years without "problems" -- until it causes a problem.
4.After we freed space, we can continue to change values of array and integer, why is this possible after free space? We don't need to reuse malloc?
This is totally Undefined behavior! After freeing the memory also the pointer still points to the same memory location. It is called Dangling Pointer.
To avoid dangling pointer, Make pointer to null
after free
!
But after freeing the memory, you need to use memory means use malloc
to allocate memory and use it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With