Here is the working code. It compiles and runs now.
Generally after freeing a pointer, people set it to NULL
to avoid confusion (so that any time a pointer is not null it points to valid memory). That avoids bugs. Also it is legal to free(NULL)
, so you don't get into very severe and hard-to- debug problems that happen if you double-free an address.
One important point, is that in this case, the parenthesis in this case (*pArr)[2]
are important, to override the operator precedence in C. If you try *pArr[2]
it assumes you mean to de-reference the pointer stored at element [2]. (*pArr)[2]
means return element at element to from the the location at the address pointed to by pArr
. The reason C assumes the other case and that you need parens in this case is that the other use is much much more common, so it is convenient.
Note: ALWAYS check return values for malloc() and function calls and have a strategy to catch and log errors. Otherwise as you start writing bigger programs you will find them extremely difficult, troublesome or nearly impossible to debug.
Another thing is to create named constants instead of literals, because then it is clear what the number is and how it is used, and if that number is needed in more than one place it can be changed in one place. It makes the program easier to read and understand.
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#define STRING_COUNT 4
char **create_array(char ***pArr);
int
main()
{
char **arr = NULL;
if (create_array(&arr) == NULL) {
fprintf(stderr, "out of memory - exiting\n");
return -1;
}
for (size_t i = 0; i < STRING_COUNT; i++) {
printf("%s\n", arr[i]);
}
for (size_t i = 0; i < STRING_COUNT; i++) {
free(arr[i]);
arr[i] = NULL;
}
free(arr);
return 0;
}
char **
create_array(char ***pArr)
{
if ((*pArr = malloc(STRING_COUNT * sizeof (char **))) == NULL) {
return NULL;
}
if (((*pArr)[0] = strdup("aaaa")) == NULL) {
return NULL;
}
if (((*pArr)[1] = strdup("bbbb")) == NULL) {
free((*pArr)[0]);
*pArr[0] = NULL;
return NULL;
}
if (((*pArr)[2] = strdup("bbbb")) == NULL) {
free((*pArr)[0]);
*pArr[0] = NULL;
free((*pArr)[1]);
*pArr[1] = NULL;
return NULL;
}
if (((*pArr)[3]= strdup("bbbb")) == NULL) {
free((*pArr)[0]);
*pArr[0] = NULL;
free((*pArr)[2]);
*pArr[1] = NULL;
free((*pArr)[2]);
*pArr[2] = NULL;
return NULL;
}
return *pArr;
}