Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freeing malloced structure in a function

I'm creating a source files containing buffer functionality that I want to use for my other library that I'm creating.

It is working correctly but I'm having trouble getting rid of the buffer structure that I'm creating in one of the functions. The following snippets should help illustrate my problem:

C header:

//dbuffer.h
...

typedef struct{
    char *pStorage;
    int *pPosition;
    int next_position;
    int number_of_strings;
    int total_size;
    }DBUFF; 
...

C source:

//dbuffer.c
...
DBUFF* dbuffer_init(char *init_pArray)
    {
    //Find out how many elements the array contains
    int size = sizeof_pArray(init_pArray);                         

    //Initialize buffer structure
    DBUFF *buffer = malloc(sizeof(DBUFF));                                       

    //Initialize the storage
    buffer->pStorage = malloc( (sizeof(char)) * (size) );

    strncpy( &(buffer->pStorage)[0] ,  &init_pArray[0] , size);
    buffer->number_of_strings = 1;

    buffer->total_size = size;
    buffer->next_position = size; //size is the next position because array allocates elements from 0 to (size-1)

    //Initialize the position tracker which keeps record of starting position for each string
    buffer->pPosition = malloc(sizeof(int) * buffer->number_of_strings );
    *(buffer->pPosition + (buffer->number_of_strings -1) ) = 0;

    return buffer;
    }

void dbuffer_destroy(DBUFF *buffer)
    {
    free(buffer->pStorage);
    free(buffer);
    }
...

Main:

#include <stdio.h>
#include <stdlib.h>
#include "dbuffer.h"


int main(int argc, char** argv)
    {
    DBUFF *buff; 

    buff = dbuffer_init("Bring the action");
    dbuffer_add(buff, "Bring the apostles");
    printf("BUFFER CONTENTS: ");
    dbuffer_print(buff); 

    dbuffer_destroy(buff);

    // Looks like it has been succesfully freed because output is garbage
    printf("%s\n", buff->pStorage);   

    //Why am I still able to access struct contents after the pointer has been freed ?
    printf("buff total size: %d\n", buff->total_size);

    return (EXIT_SUCCESS);
    }

Output:

BUFFER CONTENTS: Bring the action/0Bring the apostles/0
��/�
buff total size: 36

RUN SUCCESSFUL (total time: 94ms)

Question:

Why am I still able to access struct contents using the line below after the pointer to the struct has been freed ?

printf("buff total size: %d\n", buff->total_size);
like image 346
Shady Programmer Avatar asked Dec 01 '22 14:12

Shady Programmer


1 Answers

Once you've called free() on the allocated pointer, attempt to make use of the pointer invokes undefined behavior. You should not be doing that.

To quote C11 standard, chapter §7.22.3.4, free() function

The free() function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. [..]

It never say's anything about a cleanup, which you might be (wrongly) expecting.

Just to add clarity, calling free() does not always actually free up the allocated physical memory. It just enables that pointer (memory space) to be allocated again (returning the same pointer, for example) for successive calls to malloc() and family. After calling free(), that pointer is not supposed to be used from your program anymore but C standard does not guarantee of a cleanup of the allocated memory.

like image 50
Sourav Ghosh Avatar answered Dec 09 '22 23:12

Sourav Ghosh