Reputation: 303
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
Upvotes: 0
Views: 85
Reputation: 20037
Try return (void*)(new + 1) instead of return (void*)(new + sizeof(TMemUnit))
Pointer arithmetic (p+n) already counts in the units of sizeof(*p).
Upvotes: 0
Reputation: 993901
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));
Upvotes: 2