0

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?

3
  • 1
    For your last question, you can refer to this question Commented Oct 31, 2019 at 9:32
  • 2
    Given size_t nbytes, your printf("malloc of %10lu bytes ", nbytes); invokes undefined behavior. The proper format string for size_t is %zu. Commented Oct 31, 2019 at 9:32
  • Incidentally, casting malloc() is discouraged in modern C, since it can force code to compile even if #include <stdlib.h (the header that declares malloc() and friends) and the common result is then undefined behaviour. It was only ever necessary in (very old) versions of C that predated introduction of the void pointer into the language (so malloc() returned char *). Commented Oct 31, 2019 at 10:31

2 Answers 2

2
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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! And also I just read that free(NULL) used to cause some problems on old systems, that's why they added the check.
@NVA - That's only a concern if you've managed to find VERY old compilers and library. Even K&R C (first edition was in 1978, from memory, which predated ratification of the first C standard by over a decade) specified that free(NULL) had no effect. There were a few libraries before K&R first edition which would crash on free(NULL) but those were considered bugs even by their vendors/developers so you'd be hard pressed to find a C compiler and library with that behaviour.
1

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; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.