user72708
user72708

Reputation: 1255

C pointers, free memory

I have these structures:

typedef struct memory_slice {
    size_t startAdd; //Start of slice
    size_t dim; //Dim in bytes
    void *slice; //Chunk of memory
    struct memory_sclice *next; //Next element in list
} ms;

typedef struct heap_s {
    struct memory_slice *empty; //List of ptr to free memory
    struct memory_slice *used;
    heap_policy_t pol;
} heap_t;

I make two functions that work as constructor and destructor:

heap_t *heapCreate (size_t heapSize) {
    heap_t *p = malloc(sizeof(heap_t));

    if (heapSize != 0) {
        p->empty = malloc(sizeof(ms)); //Only one chunk
        p->empty->slice = malloc (sizeof(heapSize));
        p->empty->dim = heapSize;
    } else {
        p->empty = malloc(sizeof(ms));
        size_t ap = 1024;
        p->empty->slice = malloc (sizeof(ap));
        p->empty->dim = ap;
    }

    p->empty->startAdd = 0;
    p->empty->next = NULL;
    p->used = NULL;
    p->pol = first_fit;

    return p;
}

//Destructor of struct
void heapDestroy (heap_t *h) {
    //Free all slices
    struct memory_sclice *app;

    while (h->empty != NULL) {
        free(h->empty->slice);
        app = h->empty;
        h->empty = h->empty->next;
        free(app);
    }

    while (h->used != NULL) {
        free(h->used->slice);
        app = h->used;
        h->used = h->used->next;
        //free(app->slice);
        free(app);
    }

    free(h); //Delete main structure
}

This code works but I don't understand way I can't free memory like this "free(app->slice)" :

while (h->empty != NULL) {
        app = h->empty;
        free(app->slice);
        h->empty = h->empty->next;
        free(app);
    }

Can someone tell me where is the problem using "free(app->slice)" ??

Upvotes: 0

Views: 243

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 755010

The code supplied has a couple of references to struct memory_cslice; those need to be changed to struct memory_slice. The code doesn't compile unless you add something like:

typedef enum { first_fit, best_fit, worst_fit } heap_policy_t;

Have you got and used valgrind available to you?

There are two problematic calls to malloc() (not adjacent in the actual code):

p->empty->slice = malloc(sizeof(heapSize));
...
p->empty->slice = malloc(sizeof(ap));

In each case, the argument to sizeof() is of type size_t, so in fact the two blocks are allocating the same amount of space, and it is likely either 4 bytes or 8 bytes. Very often it is correct to use sizeof() with malloc(); this is one of the cases where it is not correct. You'd simplify your code if you wrote:

heap_t *heapCreate(size_t heapSize)
{
    heap_t *p = malloc(sizeof(heap_t));

    if (heapSize == 0)
        heapSize = 1024;
    p->empty = malloc(sizeof(ms));
    p->empty->slice = malloc(heapSize);
    p->empty->dim = heapSize;
    p->empty->startAdd = 0;
    p->empty->next = NULL;
    p->used = NULL;
    p->pol = first_fit;
    return p;
}

Of course, you should handle the cases where malloc() fails, so that should be improved to:

heap_t *heapCreate(size_t heapSize)
{
    heap_t *p = malloc(sizeof(heap_t));
    if (p != 0)
    {
        if (heapSize == 0)
            heapSize = 1024;
        if ((p->empty = malloc(sizeof(ms))) == 0)
        {
            free(p);
            return 0;
        }
        if ((p->empty->slice = malloc(heapSize)) == 0)
        {
            free(p->empty);
            free(p);
            return 0;
        }
        p->empty->dim = heapSize;
        p->empty->startAdd = 0;
        p->empty->next = NULL;
        p->used = NULL;
        p->pol = first_fit;
    }
    return p;
}

Upvotes: 1

Gary Drocella
Gary Drocella

Reputation: 337

You should use unix functions brk and sbrk if you want to build your own toy memory manager :)

It would definitely be alot easier to answer if you gave us the specific context of where you called free(app->slice) in your code, inorder for it to break. This is because you should be able free memory by doing a free(app->slice).

Upvotes: 0

user123
user123

Reputation: 9071

I believe it's because you have a typo here:

struct memory_sclice *app;

It should be memory_slice.

Currently, app is not of type memory_slice and thus slice is not a member.

Basically, you have a pointer to a struct with no definition. (Unless for some very odd reason you have a struct in there called memory_sclice :V. I'd be surprised.)

Was this error really the only one that popped up?

Upvotes: 0

Related Questions