The title maybe confusing. Suppose str
is a pointer allocated by malloc
. ptr
, of type int*
, is assigned to it and is freed as shown by the code snippet below:
char* str = malloc(64);
int* ptr = str;
free(ptr);
I've tried to compile the above code. It just gives a warning:
source_file.c: In function ‘main’:
source_file.c:10:16: warning: initialization from incompatible pointer type
int* ptr = str;
^
Does the above code invoke Undefined Behavior?
Does the above code snippet free the memory allocated by malloc
for str
?
The memory allocated using functions malloc() and calloc() is not de-allocated on their own. Hence the free() method is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of memory by freeing it. Syntax: free(ptr); Example:
Let’s look at each of them in greater detail. The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large block of memory with the specified size. It returns a pointer of type void which can be cast into a pointer of any form.
Notice how void pointer returned from the malloc () function is typecasted and then assigned to p. Memory allocated contains garbage value so do not try to dereference it before assigning proper values to it.
In line 15, the if condition checks whether the pointer returned by malloc () is null pointer or not. If p is NULL then memory allocation failed and the program terminates.
Does the above code invoke Undefined Behavior?
It depends.
From C11 draft 6.3.2.3/7:
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned) for the referenced type, the behavior is undefined.
As the alignment for a char
might be different from an int
, that is probably less restrictive, assigning a char * pc
to an int * pi
might lead to pi
being misaligned.
However for the specific example given by the OP:
char * pc = malloc(64);
int * pi = pc;
the behaviour would be defined, as (See Alter Mann's comment) malloc()
is guaranteed to return a block of memory properly aligned.
From C11 draft 7.22.3:
The pointer returned [by aligned_alloc, calloc, malloc, and realloc] if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement ...
An example which would lead to undefined behaviour, due to misalignment, is:
char * pc = malloc(64);
int * pi = pc + 1;
Does the above code snippet free the memory allocated by malloc for str?
In case the former assignment would have introduced undefined behaviour this question is irrelevant, as anything could happen with UB having been invoked already.
If else the prior assignment wouldn't have invoked UB, the call to free()
would perfectly de-allocate the block of memory referenced, as converting back the pointer value from int *
to void *
, as originally provided by malloc()
, is well defined.
From C11 draft 6.3.2.3/7 (cont/):
Otherwise, when converted back again, the result shall compare equal to the original pointer
and
From C11 draft 6.3.2.3/1:
A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer
No. It doesn't invoke undefined behaviour. The warning is simply about incompatible types which you could cast.
char* str = malloc(64);
int* ptr = (int*) str;
free(ptr);
free
does take a void pointer and the above has no problems. However, using the result of such a value may invoke undefined behaviour due to alignment of int type and char type. As such the conversion of char*
to int*
itself doesn't lead to undefined.
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