should I just let the pointer be NULL and let the coder that is using my function to handle the errors after calling my function?
Probably yes.
But not only "after" but also before, that is the coder needs to store a copy of the address the pointer being passed into your function points to. Because if the coder didn't and your function failed the program leaked memory, namly such which the pointed to address referenced.
char * p = malloc(42);
{
char * p_save = p;
f(&p_save, "");
if (NULL == p_save)
{
/* log error or what ever is needed, including freeing p and return, exit or abort */
}
else
{
p = p_save;
}
}
free(p);
Or just wrap that sick function into something that is more easy to handle:
int fex(char ** pp, const char * t)
{
char * p = *pp; /* Store a backup, just in case. */
f(pp, t);
if (NULL == *pp)
{
*pp = p; /* Opps, restore ... */
return -1; /* ... and indicate error. errno should already have been set by realloc in f. */
}
return 0; /* Good. */
}
or (a bit dirty):
char * fex(char * p, const char * t)
{
f(&p, t);
if (NULL == p)
{
return (char *) -1; /* ... and indicate error. errno should already have been set by realloc in f. */
}
return p; /* Good. */
}
Call the latter like:
char * p = malloc(42);
{
char * tmp = fex(p, "");
if ((char *) -1) == tmp)
{
perror("fex() failed");
}
else
{
p = tmp;
}
}
free(p);
f(). This would be useful if you want to handle the case wherepisNULL, for example.