NVA
NVA

Reputation: 37

Explanation about types and variables used in a malloc code

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 beNULL` 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

Answers (2)

Vlad from Moscow
Vlad from Moscow

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

Some programmer dude
Some programmer dude

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

Related Questions