Jos B
Jos B

Reputation: 117

Freeing memory pointed by members of a struct

I'm doing tests using a dynamically allocated array of struct and members of that struct before implementing it in my app but I'm not really familiar with those (hence the tests) and I'm facing bugs when freeing the members of each struct.

Am I not freeing correctly ? or is the problem when I'm allocating the memory ?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CODE_LEN 20
#define QTY_LEN 5

typedef struct {
    char* code;
    char* qty;
    int filePos;
} ENTRY;

void malloc_ptr(ENTRY**);
void realloc_ptr(ENTRY**);

int main()
{
    ENTRY *ssar;
    int i;

    malloc_ptr(&ssar);

    memcpy(ssar[0].code, "abcde", 5);
    memset(ssar[0].code + 5, 0, 1);

    printf("%s\n", ssar[0].code);

    realloc_ptr(&ssar);
    memcpy(ssar[4].code, "fghij", 5);
    memset(ssar[4].code + 5, 0, 1);

    printf("%s\n", ssar[4].code);

    //Exited with code=3221226356 here
    for(i = 0;i < 5;i ++){
        free(ssar[i].code);
        free(ssar[i].qty);
    }
    free(ssar);

    return 0;
}

void realloc_ptr(ENTRY** ssar){
    int i;

    *ssar = realloc(*ssar, 5 * sizeof(*ssar));

    for(i = 1;i < 5;i ++){
        (*ssar)[i].code = malloc(CODE_LEN * sizeof(char));
        (*ssar)[i].qty = malloc(QTY_LEN * sizeof(char));
    }
}

void malloc_ptr(ENTRY** ssar){
    *ssar = malloc(sizeof(*ssar));
    (*ssar)[0].code = malloc(CODE_LEN * sizeof(char));
    (*ssar)[0].qty = malloc(QTY_LEN * sizeof(char));
}

Thanks

Upvotes: 1

Views: 78

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

For example the function malloc_ptr

void malloc_ptr(ENTRY** ssar){
    *ssar = malloc(sizeof(*ssar));
    (*ssar)[0].code = malloc(CODE_LEN * sizeof(char));
    (*ssar)[0].qty = malloc(QTY_LEN * sizeof(char));
}

is incorrect and invokes undefined behavior.

In this statement

    *ssar = malloc(sizeof(*ssar));

you need to allocate an object of the type ENTRY instead of a pointer to object of this type. That is you need to write

    *ssar = malloc( sizeof( **ssar ) );

or

    *ssar = malloc( sizeof( ENTRY ) );

The same problem exists in the function realloc_ptr. Instead of this statement

*ssar = realloc(*ssar, 5 * sizeof(*ssar));

you have to write

*ssar = realloc(*ssar, 5 * sizeof(**ssar));

or

*ssar = realloc(*ssar, 5 * sizeof( ENTRY ));

Also it is better to use an intermediate pointer because the function can return a null-pointer. In this case the previous address of the allocated memory will be lost. For example

ENTRY *tmp = realloc(*ssar, 5 * sizeof( ENTRY ));
if ( tmp != NULL ) *ssar = tmp; 

Instead of these two statements

memcpy(ssar[0].code, "abcde", 5);
memset(ssar[0].code + 5, 0, 1);

it is simpler to write

strcpy( ssar[0].code, "abcde" );

Upvotes: 1

Related Questions