so I have a function that creates a flexible array type and all paths use calloc to define the size of the array. However when I try to destroy the struct, it says that the memory was not allocated.
typedef struct {
int size;
void *items;
} Array;
typedef enum {
CHAR,
INT,
FLOAT,
DOUBLE
} datatype;
Array *create_array(int initial_size, datatype type)
{
Array *arr = malloc(sizeof(Array));
arr->size = initial_size;
switch (type) {
case CHAR:
arr->items = (char *) calloc(5, sizeof(char));
break;
case INT:
arr->items = (int *) calloc(arr->size, sizeof(int));
break;
case FLOAT:
arr->items = (float *) calloc(arr->size, sizeof(float));
break;
case DOUBLE:
arr->items = (double *) calloc(arr->size, sizeof(double));
break;
default:
exit(1); // will handle later on
break;
}
return arr;
}
void destroy_array(Array *arr)
{
free(arr->items); // this is the line that throws the error
free(arr);
}
The exact error is:
flexibleArray(63110,0x10c3c6600) malloc: *** error for object 0x600000c21120: pointer being freed was not allocated flexibleArray(63110,0x10c3c6600) malloc: *** set a breakpoint in malloc_error_break to debug
I just don't understand why memory I'm allocating with calloc does not require to be freed.
Thanks for anyone's input!
Main Loop
There is just a lot of random code in there that I am using to test out changing the size of the array. I don't think it would affect the outcome of the destroy function.
int main() {
Array *newArr = create_array(5, INT);
int *val;
int w = 20;
val = &w;
printf("%s\n", typename(w));
((int *)newArr->items)[0] = *val;
((int *)newArr->items)[1] = 35;
((int *)newArr->items)[2] = 20;
((int *)newArr->items)[3] = 351;
((int *)newArr->items)[4] = 315;
for(int i = 0; i < newArr->size; i ) {
printf("%d\n", ((int *)newArr->items)[i]);
}
realloc(newArr->items, 10);
((int *)newArr->items)[5] = 50;
for(int i = 0; i < newArr->size; i ) {
printf("%d\n", ((int *)newArr->items)[i]);
}
destroy_array(newArr);
}
CodePudding user response:
You currently ignore the return value from realloc
. If it needs to relocate the allocated data, you get undefined behavior.
Another problem is that you allocate room for 10
bytes, not 10
int
.
Fix:
// allocate space for 10 `int`:
void* np = realloc(newArr->items, 10 * sizeof(int));
if(np) {
// realloc success
newArr->items = np;
} else {
// realloc failure
destroy_array(newArr);
return 1;
}
CodePudding user response:
Thanks to Retired Ninja and Ted Lyngmo!
Didn't see the * on the realloc documentation to see it returned a pointer to the new object. Using:
...
newArr->items = realloc(newArr->items, 10);
...
removed the error.
Thank you for the assistance!
Side note to another comment from Ted Lyngmo it was something was with generics I was playing around with. It was declared just did not put it in here...