Reputation: 117
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
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