Search code examples
cpointersmemory-leaksundefined-behaviordereference

Weird bug while passing double pointers to a function in C


Bug:
While passing a double pointer to a function the value of the fields that the pointer is pointing to seems to be dependent on some local variable of the function.
More specifically when I comment the line L(in the function "function")
Output:

In the main function: 1
In the function: 1

But when I uncomment the same line,
Output:

In the main function: 1
In the function: 0

program:

typedef struct s{
    int *value; 
}s;


s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    temp = &f;
    return temp;
}

void function(s** what)
{

//Line L:   size_t count = 0;
    printf("In the function: %d\n", (*what)->value == NULL);
}

int main()
{
    s** m = initialize();
    printf("In the main function: %d\n", (*m)->value == NULL);
    function(m);
}

What I have tried:

  • I thought that I am getting random outputs, but that was not the case as I am consistently getting the same output.
  • I tried deciphering the assembly language code but that was too cryptic for me.

Environment:

  • compiler: gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  • operating system: linux mint

Solution

  • The function initialize

    s** initialize()
    {
        s** temp = (s**)malloc(sizeof(s*));
        s* f = (s*)malloc(sizeof(s));
        f->value = NULL;
        temp = &f;
        return temp;
    }
    

    can invoke undefined behavior because it returns pointer to a local variable. And moreover it has a memory leak.

    At first a memory was allocated and its address was assigned to the variable temp

        s** temp = (s**)malloc(sizeof(s*));
    

    Then the pointer was reassigned

        temp = &f;
    

    So the allocated memory is not freed.

    The pointer is assigned by the address of a local variable

        s* f = (s*)malloc(sizeof(s));
        //...
        temp = &f;
    

    After exiting the function the variable f will not alive. So the pointer temp has an invalid value.

    It seems what you mean is the following

    s** initialize()
    {
        s** temp = (s**)malloc(sizeof(s*));
        s* f = (s*)malloc(sizeof(s));
        f->value = NULL;
        *temp = f;
        return temp;
    }
    

    If to make the changes you will get the expected result.

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct s{
        int *value; 
    }s;
    
    s** initialize()
    {
        s** temp = (s**)malloc(sizeof(s*));
        s* f = (s*)malloc(sizeof(s));
        f->value = NULL;
        *temp = f;
        return temp;
    }
    
    void function(s** what)
    {
    
    //Line L:   size_t count = 0;
        printf("In the function: %d\n", (*what)->value == NULL);
    }
    
    int main( void )
    {
        s** m = initialize();
        printf("In the main function: %d\n", (*m)->value == NULL);
        function(m);
    
        free( *m );
        free( m );
    }
    

    The program output is

    In the main function: 1
    In the function: 1