Reputation: 37
I need some explanation for some commands in this particular piece of code:
#inlcude <stdlib.h>
#define PTRS 5
char *p[PTRS];
size_t nbytes = 10;
int i;
/* Allocating memory */
for (i=0; i<PTRS; i++){
printf("malloc of %10lu bytes ", nbytes);
if ((p[i] = (char *)malloc(nbytes)) == NULL){
printf("failed\n");
} else {
printf("succeeded\n");
nbytes *= 100;
}
/* Free the memory allocated */
for (i=0; i<PTRS; i++){
if(p[i]){
free(p[i]);
p[i] = NULL;
}
}
First one is
char *p[PTRS];
Does this line declare a pointer to an array or does it declare an array of pointers to char?
p[i] = (char *)malloc(nbytes)
I understand that as i
increases, p[i]
will contain a pointer to the allocated memory called by malloc
if it's successfully processed, and p[i] will be
NULL` if no such memory can be prepared.
Second one is
if (p[i]){
free(p[i]);
p[i] = NULL;
}
This only frees memory if p[i]
has any value (in this case a pointer to the memory). What happens if we remove if(p[i])
and only use free(p[i]
and p[i] = NULL
? Can we free a NULL
pointer?
Upvotes: 0
Views: 90
Reputation: 310950
I understand that as i increases, p[i] will contain a pointer to the allocated memory called by malloc
So if you understand this when it means that p[i]
being an element of an array has the type char *
because at least in the program there is explicit casting to this type of themalloc
call in the if statement
if ((p[i] = (char *)malloc(nbytes)) == NULL){
So this declaration
char *p[PTRS];
declares an array of PTRS
elements with the tyoe char *
. I advice to write such a declarations like
char * p[PTRS];
inserting a blank after the character '*'
.
You may rewrite the declaration also the following way
char * ( p[PTRS] );
A pointer to an array of PTRS
elements of the type char
is declared the following way.
char ( *p )[PTRS];
Can we free a NULL pointer?
More precisely it would be said may we use the function free
with a null-pointer because we are not freeing a null pointer itself that in the context of your example has the automatic storage duration.
The answer is yes we may. A call of the function with a null pointer will have neither affect and is safe.
Thus this loop
for (i=0; i<PTRS; i++){
if(p[i]){
free(p[i]);
p[i] = NULL;
}
}
may be rewritten like
for (i=0; i<PTRS; i++){
free(p[i]);
p[i] = NULL;
}
Upvotes: 1
Reputation: 409166
char *p[PTRS];
is equivalent to
char *(p[PTRS]);
i.e. it's an array of pointers, not a pointer to an array. A pointer to an array would be e.g.
char (*p)[PTRS];
The clockwise/spiral rule could be helpful in deciphering declarations. As would using resource such as https://cdecl.org.
And you can pass a NULL
pointer to free
(it's a no-op) so the check isn't needed really.
Depending on the further use of p
, the p[i] = NULL
assignment might not be needed either.
Upvotes: 2