|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Recently we had some topics about this (from mr Jacob and mr McLean if
I recall correctly) I have written a small snippet that works (althought not greatly optimised), I will explain the functions now. There are 4 functions int xmalloc_init(void) /* initializes an xmalloc session, registers xmalloc_end() with atexit() if it is the first time the function is called */ void xmalloc_end(void) /* stops an xmalloc session, freeing everything allocated. can be called even if a session is not started with xmalloc_init(), and can be called two times in a row (or more) without crashing */ void * xmalloc(size_t, int) /* first argument is the size to be allocated, second argument if true, then if xmalloc fails it will return NULL. if second argument is false, (0) then xmalloc will call exit(EXIT_FAILURE) */ void xfree(void *) /* frees a pointer allocated with xmalloc(). passing NULL or a pointer that has not been allocated with xmalloc() does nothing. */ I hope it does not have any bugs. *** DO NOT MIX xfree() AND free() *** -- xmalloc.c -- /* vippstar 2008 - comp.lang.c please don't credit (nor blame ;-) if you use */ #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 */ int xmalloc_init(void); void xmalloc_end(void); void * xmalloc(size_t, int); void xfree(void *); /* implementation specific functions */ int xmalloc_resize(void); void xmalloc_clear(void); void xmalloc_remove(size_t); /* 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 ); } 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 -1; /* 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; for(n = 0; n < _xmalloc_s.sz; n++) free(_xmalloc_s.ptr[n]); 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 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--; } |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Here is an example snippet with this code.
-- snip.c -- #include "xmalloc.c" void oh_no(void) { fprintf(stderr, "Something went wrong.\n"); } int main(void) { size_t n; void *p; xmalloc_init(); atexit(oh_no); /* its just an example so i dont check return value */ for(n = 0; n < 1024; n++) (void)xmalloc(1, 0); /* no memory leak, the pointer is held somewhere */ printf("allocated 1024 xmalloc(1, 0)!\n"); xmalloc_end(); /* free our resources */ xmalloc_init(); p = xmalloc(sizeof "hello world\n", 0); strcpy(p, "hello world\n"); printf("%s", p); xfree(p); return 0; } -- snip.c -- |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
No comments?
|
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
vippstar@gmail.com wrote:
> No comments? You should have given some time between the previous threads started by jacob and Malcolm, and yours. Participants are probably too bone weary at this point to start beating the same carcass once again. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
vippstar@gmail.com wrote:
> > No comments? My preference is to have all program termination statements be located in the definition of main. xmalloc goes against that philosophy. The problem that xmalloc is a solution to, is not a real problem. It's like the problem that all keywords have more than one character in their spelling, thus making it impossible to write complicated programs because you get too tired from all of the extra typing. The solution to *that* problem has been posted occassionally by the same poster here for several years. Nobody likes it. My hard drive makes less noise when I do all of my freeing and fclosing explicitly before calling exit, even though I don't have to. -- pete |
|
![]() |
| Outils de la discussion | |
|
|