Thanks, I've tried this but it does NOT work
You can make your own allocator and freer and use them instead of
'malloc' and 'free'. In fact, you could even do:
#include <standard_stuff1.h>
#include <standard_stuff2.h>
#include <system_stuff.h>
#include "my_stuff.h"
#define malloc my_malloc
#define free my_free
Then you could use 'malloc' and 'free' but the result would be calls to
your functions instead of the implementation's.
Here's an example alternative to using 'malloc' that I haven't looked at
for a while:
/**
* Delete all lines containing
* 'ALL_IN_ONE' if you split this example
* into separate files.
*/
#define ALL_IN_ONE 1
/****
* pfxalloc.h
*
* It took several minutes to find
* a free *alloc. (No pun intended.)
*/
#ifndef PFXALLOC_H_
/* For 'offsetof' and 'size_t' */
#include <stddef.h>
/*** Macros */
#define PFXALLOC_H_
#ifndef alignof
/* Derived from Mr. Chris M. Thomasson */
#define alignof(type) \
(offsetof(struct {char c; type t;}, t))
#ifdef __alignof_is_defined
#undef __alignof_is_defined
#endif /* __alignof_is_defined */
#define __alignof_is_defined 1
#endif /* alignof */
/*** Functions */
/**
* Allocate memory for an object and an
* associated "prefix" object.
*
* @v pfx_size The "prefix" size.
* @v obj_alignment The object's alignment
* requirement.
* @v obj_size The object's size.
* @ret void * Points to the object,
* or is NULL for failure.
*/
extern void * pfxalloc(size_t, size_t, size_t);
/**
* Get an object's associated "prefix" object.
*
* @v obj The object to fetch the
* associated "prefix" for.
* @ret void * Points to the "prefix",
* or is NULL for failure.
*/
extern void * pfxget(void *);
#endif /* PFXALLOC_H_ */
/**** pfxalloc.c */
/* For 'malloc' */
#include <stdlib.h>
#if !ALL_IN_ONE
/* For 'size_t', 'ptrdiff_t' and 'NULL' */
#include <stddef.h>
/* For 'alignof' */
#include "pfxalloc.h"
#endif /* !ALL_IN_ONE */
/*** Constants */
enum cv {
cv_ptrdiff_alignment =
alignof(ptrdiff_t),
cv_zero = 0
};
/*** Functions */
/**
* The layout looks like:
* +-----+-------------+--------+--------+
* | pfx | opt_padding | offset | |
* +- -+- -+- -+ object |
* | header | |
* +----------------------------+--------+
*/
void * pfxalloc(
size_t pfx_size,
size_t obj_alignment,
size_t obj_size
) {
size_t offset_at;
ptrdiff_t * offset;
size_t header_size;
size_t total_size;
unsigned char * mem;
unsigned char * obj;
/* Sanity-check alignment value */
if (obj_alignment & (obj_alignment - 1))
return NULL;
/* Calculate the offset position */
offset_at = pfx_size;
offset_at += sizeof *offset;
/* Check for wrap-around */
if (offset_at < pfx_size)
return NULL;
--offset_at;
offset_at /= sizeof *offset;
/* Calculate the header size */
header_size = (offset_at + 1) * sizeof *offset;
/* Check for wrap-around */
if (header_size < pfx_size)
return NULL;
/* Calculate padding */
if (obj_alignment > cv_ptrdiff_alignment) {
size_t new_hdr_size = header_size;
new_hdr_size += obj_alignment;
/* Check for wrap-around */
if (new_hdr_size < header_size)
return NULL;
--new_hdr_size;
new_hdr_size /= obj_alignment;
new_hdr_size *= obj_alignment;
header_size = new_hdr_size;
}
/* Allocate storage */
total_size = header_size + obj_size;
/* Check for wrap-around */
if (total_size < pfx_size || total_size < obj_size)
return NULL;
mem = malloc(total_size);
if (!mem)
return mem;
/* Point to the object */
obj = mem + header_size;
/* Note the offset to the prefix */
offset = (ptrdiff_t *) obj - 1;
*offset = obj - mem;
return obj;
}
/* Fetch an asociated prefix for an object */
void * pfxget(void * obj) {
ptrdiff_t * offset;
unsigned char * prefix;
if (!obj)
return obj;
offset = obj;
--offset;
prefix = obj;
prefix -= *offset;
return prefix;
}
(It could probably be improved.)