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;
}