3

Giving this example function:

And giving that I can only change the else statement in the function, how should I handle a memory allocation error? I can't return some error code since the function returns void, I can't throw exceptions in C, I can't just stop the execution in a function for an error that could be minor relatively to the other things that the program is doing... 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?

The only functions I can use are the function in these libraries: stdio.h, stdlib.h, string.h, stdarg.h

Thank you!

4
  • You can return an error code if you add a retcode out parameter to f(). This would be useful if you want to handle the case where p is NULL, for example. Commented Dec 8, 2013 at 18:18
  • @H2CO3: Doing so, would lead to a memory leak. Commented Dec 10, 2013 at 18:34
  • @alk whatever, of course it would, I wasn't thinking, sorry. Commented Dec 10, 2013 at 18:40
  • @H2CO3 *p already equals NULL... and return ; is really not necessary. remove the else and document the realoc possible memory leaks. Commented Dec 11, 2013 at 0:03

4 Answers 4

2

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);
Sign up to request clarification or add additional context in comments.

Comments

2
*p = NULL;
syslog(LOG_ERR, "Memory allocation error");

4 Comments

Thanks! It's good to know that I can use in other cases the syslog function, but here I only have these libraries: stdio.h, stdlib.h, string.h, stdarg.h
Ultimately it is to the caller of the function to validate the return/output of your function. So remove syslog and go with it.
Doing as you propose leads to a memory leak.
@alk, well ultimately is is to the caller to handle this. Document the output and it's fine.
2

In class we do

printf("Error allocating memory.");
exit(1);

or simply exit(1). If your memory is full, there's not a lot you can do from there.

Comments

1

Usually this is handled like:

abort();

in many implementation of programs and libraries.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.