memory

R

RoSsIaCrIiLoIA

why not to build
a malloc_m() and a free_m() that *check* (if memory_debug=1) if
1) there are some errors in bounds of *all* allocated arrays
from them (and trace-print the path of code that make
the error and exit) just when malloc_m and free_m start.
(I use a 1100 static array for write the path (like a queue)
of called function, operator, etc and write using '+' where is
find the memory error)
2) if the pointer to free is alredy allocated from malloc_m
3) if there are memory leak at end
?

if memory_debug=0 it could do 2+3 only and
check the bounds of freed pointer (only) for errors
 
J

Jason Curl

RoSsIaCrIiLoIA said:
why not to build
a malloc_m() and a free_m() that *check* (if memory_debug=1) if
1) there are some errors in bounds of *all* allocated arrays
from them (and trace-print the path of code that make
the error and exit) just when malloc_m and free_m start.
(I use a 1100 static array for write the path (like a queue)
of called function, operator, etc and write using '+' where is
find the memory error)
2) if the pointer to free is alredy allocated from malloc_m
3) if there are memory leak at end
?

if memory_debug=0 it could do 2+3 only and
check the bounds of freed pointer (only) for errors
I've just investigated a library that does something like that for you,
but simpler. ElectricFence for Linux for example. Link with libefence
and you use it's malloc() free() routines that solves (1), (2) and (3).
I've heard Valgrind is better, but I haven't looked into it yet.
 
P

Peter Shaggy Haywood

Groovy hepcat RoSsIaCrIiLoIA was jivin' on Wed, 22 Sep 2004 08:39:46
GMT in comp.lang.c.
memory's a cool scene! Dig it!
why not to build
a malloc_m() and a free_m() that *check* (if memory_debug=1) if

Indeed, why not? Please, go right ahead.
1) there are some errors in bounds of *all* allocated arrays
from them (and trace-print the path of code that make
the error and exit) just when malloc_m and free_m start.

And how are you going to do that? How can you possibly know what
statement caused a corruption of the free memory pool or allocated
memory? Maybe you could provide a function to check this. Such a
function could be called after each suspect statement to test whether
things have become corrupted. If it were me, I'd create my own
allocation routines so I could have access to the free memory pool and
allocated memory for this very purpose.
(I use a 1100 static array for write the path (like a queue)
of called function, operator, etc and write using '+' where is
find the memory error)
2) if the pointer to free is alredy allocated from malloc_m
3) if there are memory leak at end

These two wouldn't be so hard. You just keep the address of every
block of memory dynamically allocated. Then you can check pointers
passed to free_a() against them and free the coresponding block, if it
is valid, removing your internal copy of the pointer as you do. You
can also check whether there are any allocations left un-freed upon
program exit by seeing whether you have any of these internal pointers
left over. Easy!
if memory_debug=0 it could do 2+3 only and
check the bounds of freed pointer (only) for errors

Or it could just cut out all the overhead and simply call malloc()
and free(). Or, better still, call it MEMORY_DEBUG and make it a
macro, then define two function-like macros, say MALLOC() and FREE().
If defined, you use your allocation/deallocation wrappers, otherwise
malloc() and free(). for example:

#ifdef MEMORY_DEBUG
#define MALLOC(s) malloc_a(s)
#define FREE(p) free_a(p)
#else
#define MALLOC(s) malloc(s)
#define FREE(p) free(p)
#endif

Then, in code, use these macros. Eg.:

char *foo;

foo = MALLOC(42);
if(!foo)
{
/* allocation failure - handle somehow */
}

/* use foo */

FREE(foo);

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
R

RoSsIaCrIiLoIA

I've just investigated a library that does something like that for you,
but simpler. ElectricFence for Linux for example. Link with libefence
and you use it's malloc() free() routines that solves (1), (2) and (3).
I've heard Valgrind is better, but I haven't looked into it yet.

For me my is better with that
I have found (and to correct) 3 memory bounds errors. In this way if I
find a memory error to correct it is in twinkling of an eye.
 
R

RoSsIaCrIiLoIA

Groovy hepcat RoSsIaCrIiLoIA was jivin' on Wed, 22 Sep 2004 08:39:46
GMT in comp.lang.c.
memory's a cool scene! Dig it!


Indeed, why not? Please, go right ahead.


And how are you going to do that? How can you possibly know what
statement caused a corruption of the free memory pool or allocated
memory? Maybe you could provide a function to check this. Such a
function could be called after each suspect statement to test whether
things have become corrupted. If it were me, I'd create my own
allocation routines so I could have access to the free memory pool and
allocated memory for this very purpose.

Yes. I write in every function
if(libero_m)
init_w("name_of_funct");
if the function doesn't use malloc_m or free_m (that check the memory
if libero_m!=0) in that function I write a "controlla_m("");" too.

And with this I should find in name_ array the function name where
there is the memory error.
When I see the function that has a bound error I use
controlla("label"); for see where is the instruction that write in
memory out of bounds (or corrupt pointer to free).
I have copied that by hands excuse for errors


static unsigned yuyuy=0;
typedef double Align;

union header {
struct {union header *ptr;
unsigned size;
}s;
Align x;
}

typedef union header Header;
static Header base;
static Header *freep=NULL;

char name_[1100] = {0};
chan memo_[ 300] = {0};
int n_i_ = 0 ;
int libero_m_ = 0 ;

typedef struct {
void *p;
unsigned size;
unsigned piu;
unsigned meno;
}vettore_array;

static vettore_array **p_p_p_=0;
static unsigned i_i_i_=0;
static unsigned m_m_m_=0;

static char **list_=0;
static unsigned list_i_=0;
static unsigned list_m_=0;

static int mem_init(unsigned siz)
{vettore_array **pp;
unsigned j;
/*------------------------*/
if(p_p_p_==0)
{pp = (vettore_array**) malloc((siz+1) * sizeof *pp);
if(pp==0) return 0;
for( j=0; j<siz; ++j)
{pp[j]=(vettore_array*) malloc(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
for(--j; j!=0; --j)
free((void*) pp[j] );
free((void*) pp[0]); free((void*) pp);
return 0;
}
}
}
else {if(siz==m_m_m_) return 1;
else if(siz<m_m_m_)
/* dovrebbe distruggere la memoria eccessiva*/
{if(siz<=i_i_i_) return 1;
for(j=siz; j<m_m_m_; ++j)
free((void*) p_p_p_[j]);
pp=(vettore_array**)realloc(p_p_p_, (siz+1)* sizeof *pp);
if(pp==0) { m_m_m_= siz; return 1;}
/* forse qui segnalare la cosa ? */
goto label;
}
pp=(vettore_array**)
realloc((void*)p_p_p_, (siz+1)* sizeof *pp);
if(pp==0) return 0;
if( siz> i_i_i_ )
{for(j=i_i_i_; j<siz; ++j)
{pp[j]=(vettore_array*)
malloc(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
for(--j; j!=0; --j)
free((void*) pp[j] );
free((void*) pp[0]);
return 0;
}
}
}
}
label: ;
m_m_m_= siz; p_p_p_=pp; return 1;
}

#define MEM_LIMIT 100000
#define MAX_ARRAYS 255

void* malloc_m(unsigned nbytes)
{Header *p, *prevp;
unsigned nunits, *k, *kk, led, size;
Header* morecore(unsigned);
unsigned verifica_all_m(void);
void stato_mem(void);
/*------------------------------------*/
/***************************************************/
if(libero_m)
/* nel caso libero_m!=0 controlla tutta la memoria dinamica*/
{if(verifica_all_m()==0)
stato_mem();
}
if(i_i_i_>MEM_LIMIT || nbytes==0) return 0;
if(i_i_i_>=m_m_m_)
{if(mem_init(i_i_i_ + MAX_ARRAYS) == 0) return 0;}
/***************************************************/
nunits = nbytes + sizeof(Header);
nunits = nunits/sizeof(Header) +
((nunits%sizeof(Header) > sizeof(unsigned)) ? 1 : 0) + 1;
if( (prev=freep)== NULL ) /* non esiste free list */
{ base.s.ptr=freep=prevp=&base; base.s.size=0; }
for( p=prevp->s.ptr; ; prevp=p, p=p->s.ptr )
{if(p->s.size>=nunits)
{if(p->s.size==nunits)
prevp->s.ptr = p->s.ptr;
else
{p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
/*******************************/
size = nbytes;
led = (size % sizeof(unsigned) !=0 ) ? 1: 0;
k = (unsigned*) (p+1); kk=k; --k;
p_p_p_[i_i_i_]->meno = *k;
p_p_p_[i_i_i_]->piu = kk[size/sizeof(unsigned) + led];
p_p_p_[i_i_i_]->size = size;
p_p_p_[i_i_i_]->p = (void*) (p+1);
/*******************************/
return (void*) (p+1);
}
if(p==freep) /* la free list e' terminata */
{++yuyuy;
if((p=morecore(nunits)) == NULL)
return NULL; /* nessuna memoria */
}
}
}

/* verifica_all_m(): Ritorna il numero degli elementi;
se il numero degli elementi e' zero ritorna (unsigned)(-1)
se errore (bounds error) ritorna 0
*/
unsigned verifica_all_m(void)
{unsigned j, *k, *kk, xk, xkk, led;
/*--------------------------------*/
if(p_p_p_== 0 || i_i_i_==0 ) return (unsigned)-1;
for( j=0; j< i_i_i_ ; ++j)
{k = (unsigned*) (p_p_p_[j]->p); kk=k; --k;
led = (p_p_p_[j]->size % sizeof(unsigned) !=0 ) ? 1: 0;
if( (xk=kk[p_p_p_[j]->size/sizeof(unsigned) + led])
!= (xkk=p_p_p_[j]->piu))
{sprintf(memo_, "verifica memoria sformento +:
p=%5 size=%5u p[-1]=%5u p[sup]=%5u n:v=%5u:%5u",
p_p_p_[j]->p, p_p_p_[j]->size, p_p_p_[j]->meno, xkk, xk, xkk);
if(n_i_ > 2) name_[ n_i_ - 2]='+';
return 0;
}
if( (xk=*k) != (xkk=p_p_p_[j]->meno))
{sprintf(memo_, "verifica memoria sformento -:
p=%5 size=%5u p[-1]=%5u p[sup]=%5u n:v=%5u:%5u",
p_p_p_[j]->p, p_p_p_[j]->size, xkk, p_p_p_[j]->piu, xk, xkk);
if(n_i_ > 2) name_[ n_i_ - 2]='-';
return 0;
}
}
return i_i_i_;
}

static void free_list_m(void)
{while(list_i != 0)
{--list_i_; free(list_[list_i_]); }
free(list_); list_=0; list_m_=0; freep=NULL;
}

static void free_vettore_m(void)
{if(p_p_p_==0) { m_m_m_ =0; i_i_i_=0; return ; }
while(i_i_i_ != 0)
{--i_i_i_; free((void*) p_p_p_[i_i_i_]);}
free((void*) p_p_p_);
p_p_p_=0; m_m_m_=0;
}


/* Non usare free_all_m() ma free_a_i_m() nel caso che ci sono
oggetti allocati da costruttori del c++
(gli oggetti *fuori* da una qualsiasi procedura finiscono quando
si chiude l'ultima istruzione del main ma e' il distruttore
che compie operazioni anche dopo l'ultima istruzione del main() )
*/
void free_all_m(void){free_vettore_m(); free_list_m();}

void free_a_i_m(void)
{if(i_i_i_==0)
{free_vettore_m(); free_list_m();
printf("Memoria dinamica liberata\n");
}
}

#define NALLOC 1024

static Header* morecore(unsigned nu)
{char *cp, **p;
Header *up;
unsigned len;
/*------------------*/
if(nu<NALLOC) nu=NALLOC;
cp = (char*) malloc(nu * sizeof(Header));
if(cp==0) return 0;
if(list_i_ <= list_m_)
{len = (list_m_==0 ? 128: 2*list_m_);
p = (char**) realloc(list_, len * sizeof *p);
if(p==0)
{ free(cp); return 0;}
list_ = p;
list_m = len;
}
list_[list_i_++] = cp;
up=(Header*) cp;
up->s.size = nu;
inserisci((void*) (up + 1), 1, 0); /* inserisce nella free list*/
return freep;
}

void leggi_mem(void)
{Header *u, *v;
unsigned j;
/*----------------*/
for(u=freep; u!=0 ; )
{
printf("|v=%u s=%u|",
(unsigned)u/(unsigned)sizeof(Header), u->s.size);
if(u->s.ptr==freep) break; /* fatto il giro completo */
v = u->s.ptr;
if((u + u->s.size) != v)
{
j = (unsigned)(v-u) - u->s.size;
if(j<123456) printf("%u", j);
else printf("#");
}
u = v;
}
}

void stato_mem(void)
{unsigned j;
leggi_mem(); fflush(stdout);
printf("\nRapporto memoria dinamica");
printf("Memoria richiesta dal sistema = %u vola/e", yuyuy);
j=verifica_all_m();
if(j!=0 && j!= -1) printf("%u vettori allocati con successo\n", j);
else { if(j==0) goto label;
printf("Tutto bene. ");
j=verifica_m(0, 0);
if(j==1) printf("Sia la base sia il contatore sono NULLI\n");
else if(j==2) printf("Il contatore e' nullo ma la base no\n");
else {label: ;
printf("Errore nella memoria\n");
printf("memo=%s name=%s \n", memo_, name_);
free_vettore_m(); free_list_m();
exit(1);
}
}
}

void controlla_m(char* st)
{
if(st)
{printf("!%s!", st); fflush(stdout);}
if(verifica_all_m()==0)
{printf("Errore!");
fflush(stdout);
stato_mem();
}
}

void free_m(void* ap)
{if(ap==0) return;
if(libero_m)
{if(verifica_all_m()==0)
stato_mem();
}
if(verifica_m(ap, &j))
{printf("free_m():"); stato_mem();
free_vettore_m(); free_list_m(); exit(1);
}
inserisci(ap, 0, j);
}


/* scrive come in un tabellone rotante
l'ultima parola scritta e' seguita da '#'
*/
void init_w(const char *nam)
{unsigned i, j;
/*---------------*/
if(nam==0) return 0;
if(n_i_ > 2)
name_[n_i_ - 1] = '|';
if( n_i_ >= 1016 )
n_i_ = 0;
for(i=n_i_, j=0; j<15 && nam[j]!=0; ++i, ++j)
name_=nam[j];
for( ; j< 15; ++i, ++j)
name_ =' ';
name_='#';
n_i_ += 16;
}
 
R

RoSsIaCrIiLoIA

void* malloc_m(unsigned nbytes)
{Header *p, *prevp;
unsigned nunits, *k, *kk, led, size;
Header* morecore(unsigned);
unsigned verifica_all_m(void);
void stato_mem(void);
/*------------------------------------*/
/***************************************************/
if(libero_m)
/* nel caso libero_m!=0 controlla tutta la memoria dinamica*/
{if(verifica_all_m()==0)
stato_mem();
}
if(i_i_i_>MEM_LIMIT || nbytes==0) return 0;
if(i_i_i_>=m_m_m_)
{if(mem_init(i_i_i_ + MAX_ARRAYS) == 0) return 0;}
/***************************************************/
nunits = nbytes + sizeof(Header);
nunits = nunits/sizeof(Header) +
((nunits%sizeof(Header) > sizeof(unsigned)) ? 1 : 0) + 1;
if( (prev=freep)== NULL ) /* non esiste free list */
{ base.s.ptr=freep=prevp=&base; base.s.size=0; }
for( p=prevp->s.ptr; ; prevp=p, p=p->s.ptr )
{if(p->s.size>=nunits)
{if(p->s.size==nunits)
prevp->s.ptr = p->s.ptr;
else
{p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
/*******************************/
size = nbytes;
led = (size % sizeof(unsigned) !=0 ) ? 1: 0;
k = (unsigned*) (p+1); kk=k; --k;
p_p_p_[i_i_i_]->meno = *k;
p_p_p_[i_i_i_]->piu = kk[size/sizeof(unsigned) + led];
p_p_p_[i_i_i_]->size = size;
p_p_p_[i_i_i_]->p = (void*) (p+1);
^^^^^^^^^^^^^^^
p_p_p_[i_i_i_++]->p = (void*) (p+1);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
EmeliaBryc

Latest Threads

Top