Search code examples
cpointerswarningsdangling-pointer

Dangling object warning in free after realloc failure


I'm finalizing my function for safe string retrieval and decided to turn my compiler warnings up to see if any of my code raised any flags.

Currently I am receiving the following compiler warnings on Pelles C IDE:

stringhandle.c(39): warning #2800: Potentially dangling object 'str' used after call to function 'realloc'.
stringhandle.c(50): warning #2800: Potentially dangling object 'str' used after call to function 'realloc'.

Here is my function (read below if you would rather read the question in it's entirety before reading code):

char *getstr(void)
{
    char *str, *tmp;
    int bff = STRBFF, ch = -1, pt = 0;

    if(!(str = malloc(bff)))
    {
        printf("\nError! Memory allocation failed!");
        return 0x00;
    }
    while(ch)
    {
        ch = getc(stdin);
        if (ch == EOF || ch == '\n' || ch == '\r') ch = 0;
        if (bff <= pt)
        {
            bff += STRBFF; 
            if(!(tmp = realloc(str, bff))) 
            {
                free(str);  //line 39 triggers first warning
                str = 0x00;
                printf("\nError! Memory allocation failed!");
                return 0x00;
            }
            str = tmp;
        }
        str[pt++] = (char)ch;
    }
    str[pt] = 0x00;
    if(!(tmp = realloc(str, pt)))
    {
        free(str); //line 50 triggers second warning
        str = 0x00;
        printf("\nError! Memory allocation failed!");
        return 0x00;
    }
    str = tmp;
    return str;
}

I think understand why I am being warned that str may be dangling. I am freeing the allocated space pointed to by str if an error occurs, however my function has no further calls to str after it being freed. As a fix, I just tried doing free(str) followed by str = 0x00. Shouldn't that make the pointer str no longer dangling? Does it have something to do with my tmp pointer? I don't free or set tmp to 0x00 either, since it should already be 0x00 if realloc fails. But should I be setting it to 0x00 on success, since it is still technically pointing exactly where str is and is no longer needed?

In short:

  1. Why is my compiler warning that str may be dangling?
  2. How can I remove the warning?
  3. Am I handling my tmp pointer correctly?

Solution

  • Just to illustrate my points:

    #include <stdio.h>
    #include <stdlib.h>
    
    static inline void * myrealloc(void *org, size_t newsize)
    {
    char * new;
    new = realloc(org, newsize);
    if (!new) {
            fprintf(stderr, "\nError! Memory allocation failed!\n");
            free (org);
            return NULL;
            }
    return new;
    }
    
    char *getstr(void)
    {
    #define STRBFF 256
    
        char *str = NULL;
        size_t size , used ;
    
        for (size=used=0; ; ) {
            int ch;
            if (used >=size) {
                str = myrealloc(str, size += STRBFF);
                if(!str) return NULL;
            }
            ch = getc(stdin);
            if (ch == EOF || ch == '\n' || ch == '\r') ch = 0;
            str[used++] = ch;
            if (!ch) break;
        }
        str = myrealloc(str, used);
        return str;
    }
    

    Now, if your compiler supports inlining, the calls to myrealloc() will be replaced by the equivalent of your original code, and the actual myrealloc()function will virtually disappear. (check the disassembled output).