Home > OS >  Malloc is throwing an error for pointer being freed
Malloc is throwing an error for pointer being freed

Time:06-11

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...

  • Related