V
vippstar
I have posted a previous version of this code some weeks ago which
unfortunately got no replies.
I am reposting this and I hope to see comments from c.l.c people.
You can use this code as you want, credits are not required.
Hopefully this is portable to any system and doesn't invoke undefined
behavior anywhere.
I also don't see how my code would not work with system specific
concepts such as processes and threads.
(However, receiving a signal while one of the following functions does
something will most likely break things)
This'll be the last time I am posting this (so I won't bother you
again
Hopefully I'll get some opinions.
-- xmalloc.c --
/*
vippstar 2008 - comp.lang.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _xmalloc_chunk_size 128
/* global struct of pointers allocated
all members initialized to 0/NULL because
it is global */
struct {
void ** ptr;
size_t sz; /* pointers initialized */
size_t total; /* total pointers allocated */
} _xmalloc_s;
/* user functions */
/* inits an xmalloc session, registers xmalloc_end if
it's the first time it's called, calling it while
there is an xmalloc session won't do anything */
int xmalloc_init(void);
/* ends an xmalloc session, freeing all resources,
can be called even if there was no xmalloc_init() before */
void xmalloc_end(void);
/* allocates memory like malloc(). if the allocation fails,
xmalloc looks at the second argument to see what to do
if the second argument is true, xmalloc will return NULL
if false, xmalloc will exit(EXIT_FAILURE); */
void * xmalloc(size_t, int);
/* frees a pointer previously allocated with xmalloc.
passing NULL or a pointer not allocated with xmalloc
won't do anything */
void xfree(void *);
/* frees all pointers allocated with xmalloc() in the currect
xmalloc session */
void xfreeall(void);
/* implementation specific functions */
int xmalloc_resize(void);
void xmalloc_clear(void);
void xmalloc_remove(size_t);
#ifdef DEBUG
/* debug function */
void xmalloc_debug(void);
void xmalloc_debug(void) {
printf(
"ptr -> %p\n"
"sz -> %zu\n"
"total -> %zu\n\n",
(void *)_xmalloc_s.ptr, _xmalloc_s.sz,
_xmalloc_s.total
);
}
#endif
void xmalloc_clear(void) {
_xmalloc_s.ptr = NULL;
_xmalloc_s.sz = 0;
_xmalloc_s.total = 0;
}
int xmalloc_init(void) {
static int first_time = 0;
if(_xmalloc_s.ptr)
return 0; /* xmalloc already initialized */
_xmalloc_s.ptr = malloc(_xmalloc_chunk_size * sizeof
*_xmalloc_s.ptr);
if(_xmalloc_s.ptr == NULL)
return -1;
if(first_time == 0) {
if(atexit(xmalloc_end) == -1) {
free(_xmalloc_s.ptr);
return -1;
}
first_time = 1;
}
_xmalloc_s.total = _xmalloc_chunk_size;
return 0;
}
int xmalloc_resize(void) {
void *tmp;
if(_xmalloc_s.ptr == NULL)
return -1;
tmp = realloc(_xmalloc_s.ptr, (_xmalloc_s.total +
_xmalloc_chunk_size) *
sizeof *_xmalloc_s.ptr);
if(tmp == NULL)
return -1;
_xmalloc_s.ptr = tmp;
_xmalloc_s.total += _xmalloc_chunk_size;
return 0;
}
void xmalloc_end(void) {
size_t n;
xfreeall();
free(_xmalloc_s.ptr);
xmalloc_clear();
}
/* opt = 0 we exit, opt = 1 we return NULL */
void * xmalloc(size_t size, int opt) {
if(_xmalloc_s.sz == _xmalloc_s.total) {
/* we need to resize */
if(xmalloc_resize() == -1) {
if(opt == 0)
exit(EXIT_FAILURE);
return NULL;
}
}
_xmalloc_s.ptr[_xmalloc_s.sz] = malloc(size);
if(_xmalloc_s.ptr[_xmalloc_s.sz] == NULL) {
if(opt == 0)
exit(EXIT_FAILURE);
return NULL;
}
_xmalloc_s.sz++;
return _xmalloc_s.ptr[_xmalloc_s.sz - 1];
}
void xfree(void * ptr) {
size_t n;
if(ptr != NULL) {
for(n = 0; n < _xmalloc_s.sz; n++)
if(ptr == _xmalloc_s.ptr[n]) {
xmalloc_remove(n);
free(ptr);
}
}
}
void xfreeall(void) {
size_t n;
for(n = 0; n < _xmalloc_s.sz; n++)
free(_xmalloc_s.ptr[n]);
_xmalloc_s.sz = 0;
}
void xmalloc_remove(size_t n) {
if(n != _xmalloc_s.sz - 1)
memmove(&_xmalloc_s.ptr[n], &_xmalloc_s.ptr[n+1],
(_xmalloc_s.sz - n - 1) * sizeof *_xmalloc_s.ptr);
_xmalloc_s.sz--;
}
unfortunately got no replies.
I am reposting this and I hope to see comments from c.l.c people.
You can use this code as you want, credits are not required.
Hopefully this is portable to any system and doesn't invoke undefined
behavior anywhere.
I also don't see how my code would not work with system specific
concepts such as processes and threads.
(However, receiving a signal while one of the following functions does
something will most likely break things)
This'll be the last time I am posting this (so I won't bother you
again
Hopefully I'll get some opinions.
-- xmalloc.c --
/*
vippstar 2008 - comp.lang.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _xmalloc_chunk_size 128
/* global struct of pointers allocated
all members initialized to 0/NULL because
it is global */
struct {
void ** ptr;
size_t sz; /* pointers initialized */
size_t total; /* total pointers allocated */
} _xmalloc_s;
/* user functions */
/* inits an xmalloc session, registers xmalloc_end if
it's the first time it's called, calling it while
there is an xmalloc session won't do anything */
int xmalloc_init(void);
/* ends an xmalloc session, freeing all resources,
can be called even if there was no xmalloc_init() before */
void xmalloc_end(void);
/* allocates memory like malloc(). if the allocation fails,
xmalloc looks at the second argument to see what to do
if the second argument is true, xmalloc will return NULL
if false, xmalloc will exit(EXIT_FAILURE); */
void * xmalloc(size_t, int);
/* frees a pointer previously allocated with xmalloc.
passing NULL or a pointer not allocated with xmalloc
won't do anything */
void xfree(void *);
/* frees all pointers allocated with xmalloc() in the currect
xmalloc session */
void xfreeall(void);
/* implementation specific functions */
int xmalloc_resize(void);
void xmalloc_clear(void);
void xmalloc_remove(size_t);
#ifdef DEBUG
/* debug function */
void xmalloc_debug(void);
void xmalloc_debug(void) {
printf(
"ptr -> %p\n"
"sz -> %zu\n"
"total -> %zu\n\n",
(void *)_xmalloc_s.ptr, _xmalloc_s.sz,
_xmalloc_s.total
);
}
#endif
void xmalloc_clear(void) {
_xmalloc_s.ptr = NULL;
_xmalloc_s.sz = 0;
_xmalloc_s.total = 0;
}
int xmalloc_init(void) {
static int first_time = 0;
if(_xmalloc_s.ptr)
return 0; /* xmalloc already initialized */
_xmalloc_s.ptr = malloc(_xmalloc_chunk_size * sizeof
*_xmalloc_s.ptr);
if(_xmalloc_s.ptr == NULL)
return -1;
if(first_time == 0) {
if(atexit(xmalloc_end) == -1) {
free(_xmalloc_s.ptr);
return -1;
}
first_time = 1;
}
_xmalloc_s.total = _xmalloc_chunk_size;
return 0;
}
int xmalloc_resize(void) {
void *tmp;
if(_xmalloc_s.ptr == NULL)
return -1;
tmp = realloc(_xmalloc_s.ptr, (_xmalloc_s.total +
_xmalloc_chunk_size) *
sizeof *_xmalloc_s.ptr);
if(tmp == NULL)
return -1;
_xmalloc_s.ptr = tmp;
_xmalloc_s.total += _xmalloc_chunk_size;
return 0;
}
void xmalloc_end(void) {
size_t n;
xfreeall();
free(_xmalloc_s.ptr);
xmalloc_clear();
}
/* opt = 0 we exit, opt = 1 we return NULL */
void * xmalloc(size_t size, int opt) {
if(_xmalloc_s.sz == _xmalloc_s.total) {
/* we need to resize */
if(xmalloc_resize() == -1) {
if(opt == 0)
exit(EXIT_FAILURE);
return NULL;
}
}
_xmalloc_s.ptr[_xmalloc_s.sz] = malloc(size);
if(_xmalloc_s.ptr[_xmalloc_s.sz] == NULL) {
if(opt == 0)
exit(EXIT_FAILURE);
return NULL;
}
_xmalloc_s.sz++;
return _xmalloc_s.ptr[_xmalloc_s.sz - 1];
}
void xfree(void * ptr) {
size_t n;
if(ptr != NULL) {
for(n = 0; n < _xmalloc_s.sz; n++)
if(ptr == _xmalloc_s.ptr[n]) {
xmalloc_remove(n);
free(ptr);
}
}
}
void xfreeall(void) {
size_t n;
for(n = 0; n < _xmalloc_s.sz; n++)
free(_xmalloc_s.ptr[n]);
_xmalloc_s.sz = 0;
}
void xmalloc_remove(size_t n) {
if(n != _xmalloc_s.sz - 1)
memmove(&_xmalloc_s.ptr[n], &_xmalloc_s.ptr[n+1],
(_xmalloc_s.sz - n - 1) * sizeof *_xmalloc_s.ptr);
_xmalloc_s.sz--;
}