0
votes

I am trying to write simple memory manager (I should really say memory tracker) in my C program.

I am basically creating doubly linked list of allocated blocks where I put pointers on previous and next on start of each block. Malloc procedure looks like this:

    typedef struct MemUnit TMemUnit;
    struct tMemUnit
    {
        TMemUnit *prev;
        TMemUnit *next;
    }

    TMemUnit *new = malloc(sizeof(TMemUnit) + wantedSize);
    if (new == NULL)
        /* ERROR */
    else
    {
        if (memFirst == NULL) {
            memFirst = new;
            memLast = new;
            new->prev = NULL;
            new->next = NULL;
        } else {
            new->prev = memLast;
            new->next = NULL;
            memLast->next = new;
            memLast = new;
    }
    return (void *)(new + sizeof(TMemUnit));

The problem is segmentation faults on places where was none before.

Valgrind also gives Invalid read/write errors.

==22872== Invalid write of size 4
==22872==    at 0x400FF1: main (test-memory.c:40)
==22872==  Address 0x54d51b0 is not stack'd, malloc'd or (recently) free'd

When I print addresses of allocated block (wantedSize = 20 * sizeof(int), trying to write first int) for this error they look ok:

new --> 0x54d5030
new + sizeof(TMemUnit) + wantedSize --> 0x54d5430

I can't figure out where is my mistake.

Thanks

3
I would consider avoiding the use of the C++ keyword new.Jonathon Reinhart
Not a problem here. Plain C program.user978734
I know, but C can be compiled by C++ compilers, and it's good to write reusable codeJonathon Reinhart

3 Answers

2
votes

The problem may lie here:

return (void *)(new + sizeof(TMemUnit));

Your new pointer is of type TMemUnit *, so by the rules of C pointer arithmetic, you will be adding sizeof(TMemUnit) * sizeof(TMemUnit) bytes, which is too many. Instead, try:

return (void *)((char *)new + sizeof(TMemUnit));
0
votes

You may want to return (void *)((char *)new + sizeof(TMemUnit));

0
votes

Try return (void*)(new + 1) instead of return (void*)(new + sizeof(TMemUnit))

Pointer arithmetic (p+n) already counts in the units of sizeof(*p).