¬
¬a\\/b
is it possible that a
malloc function that use a nobody student
is better than all yours
How many errors do you see?
Bug1: memory<13MB
Bug2:
it seems do you have to write you own sprintf "Ps_m"
Ps_m(char* out, int len, char* fmt, ...)
that has the len of array in the second arg
#include <windows.h>
#include <winbase.h>
#include <wincon.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <winuser.h>
#include "winb.h"
#define IVA_ INVALID_HANDLE_VALUE
#define P printf
#define W while
#define F for
#define R return
/* MEM_LIMIT e' il limite del numero di diversi puntatori
ritornati da malloc_m */
#define MEM_LIMIT 200000
#define MAX_ARRAYS 255
/*************************CCCCCCC**********************************/
#ifdef __cplusplus
extern "C" {
#endif
void* malloc_sys(int n)
{if(n<0) R 0;
R (void*)LocalAlloc(LMEM_FIXED, n);
}
void free_sys(void* p){ LocalFree(p); }
void* realloc_sys(void *p, int nbytes)
{int k;
uns a, r, j, i;
char *p1, *p2;
if(nbytes<0) R 0;
k=LocalSize(p);
if(k<0) R 0;
p1= (char*) LocalAlloc(LMEM_FIXED, nbytes);
if(p1==0) R 0;
i = k<=nbytes? k: nbytes;
a=i/(sizeof(int)); r=i&(sizeof(int)-1);
F(j=0, p2=(char*)p; j<a; ++j)
((int*)p1)[j]=((int*)p2)[j];
F(i=4*j, r+=i; i<r; ++i)
p1=p2;
LocalFree(p);
R p1;
}
#define NALLOC 1024
// 1024 /* numero minimo di unita' richieste */
// 1024*256*8=1024*1024*2 = 2 mega
static unsigned yuyuy=0;
typedef double Align; /* per allineare alla double */
union header { /* header del blocco */
struct {union header* ptr; /* blocco successivo in free list */
unsigned size; /* dimensione di questo blocco */
}s;
Align x; /* forza l'allineamento dei blocchi */
}; /* sizeof header == 4+4 = 8 */
typedef union header Header;
static Header base; /* lista vuota per iniziare */
static Header *freep=NULL; /* inizio della free list */
static char name_ [ 1100 ] = {0}; /* name_== nome routines
chiamate */
static char memo_ [ 300 ] = {0}; /* stringa ove errori
trovati in memoria */
static int n_i_ = 0 ;
int libero_m_ = 0 ; /* libero_m_==1 controllo tutti i
vettori a
ogni chiamate di free(); serve insieme a name_ per individuare le
routines che
sovrascrivono la memoria che non hanno (e.g. if(libero_m_)
init_w("nome_routines") */
typedef struct {
void *p;
unsigned size;
unsigned piu;
unsigned meno;
}vettore_array;
static vettore_array **p_p_p_=0; /* lista di struct di puntatori
ritornati da malloc_m */
static int i_i_i_=0; /* attuale indice nella lista */
static int m_m_m_=0; /* massimo indice nella lista */
static char **list_ =0; /* lista dei vettori richiesti al
sys */
static int list_i_=0;
static int list_m_=0;
static int show_si =0;
static int mem_init(int siz)
{vettore_array **pp;
int j;
/*---------------------*/
//P("p_p_p_=%p i_i_i_==%u siz=%u ", (void*) p_p_p_, i_i_i_, siz );
if(siz<0) R 0;
if(p_p_p_==0)
{pp= (vettore_array**) malloc_sys( (siz+1) * sizeof *pp );
if(pp==0) R 0;
F( j=0; j<siz; ++j)
{pp[j]= (vettore_array*) malloc_sys(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
F( --j ; j!=0 ; --j)
free_sys( (void*) pp[j] );
free_sys((void*) pp[0]); free_sys((void*) pp); R 0;
}
}
show_si=0;
}
else { if(siz==m_m_m_) R 1;
else if(siz < m_m_m_) /* dovrebbe distruggere la
memoria eccessiva */
{ if(siz<=i_i_i_) R 1; /* la 1024ma volta che viene
chiamato free_m()*/
F(j=siz; j<m_m_m_; ++j) // v[0]...v[size]=size+1
free_sys((void*) p_p_p_[j]);
pp=(vettore_array**) realloc_sys(p_p_p_, (siz + 1) *
sizeof *pp );
if(pp==0) {P("Fallimento realloc\n"); m_m_m_ = siz; R
1;}
/* ritorna senza cambiare niente */
goto label;
}
pp= (vettore_array**) realloc_sys( (void*) p_p_p_, (siz + 1)
* sizeof *pp);
if(pp==0) {P("Fallimento realloc\n"); R 0;}
if( siz > i_i_i_)
{ F( j=i_i_i_; j<siz; ++j)
{
pp[j]= (vettore_array*) malloc_sys(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
F( --j ; j!=0 ; --j)
free_sys( (void*) pp[j] );
free_sys((void*) pp[0]); R 0;
}
}
}
}
label: ;
m_m_m_ = siz; p_p_p_=pp; R 1;
}
/* malloc_m: allocatore di memoria */
void* malloc_m(unsigned nbytes)
{Header *p, *prevp;
unsigned nunits, *k, *kk, led, size;
double dnm;
Header* morecore(unsigned);
unsigned verifica_all_m( void );
void stato_mem(void);
/*-------------------------------*/
if(libero_m_)
{if(verifica_all_m()==0) stato_mem();}
if(i_i_i_>MEM_LIMIT || nbytes==0 ) R 0;
if(i_i_i_>=m_m_m_)
{if(mem_init( i_i_i_ + MAX_ARRAYS ) == 0) R 0;}
nunits = nbytes + sizeof(Header);
nunits = nunits/sizeof(Header) +
(( nunits%sizeof(Header) >sizeof(unsigned) ) ? 1: 0) + 1;
if((prevp=freep)==NULL) /* non esiste la 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) /* spazio insufficiente */
{if(p->s.size==nunits) /* esattamente */
{prevp->s.ptr = p->s.ptr;}
else /* alloca la parte finale */
{p->s.size -= nunits;
p += p->s.size;
p->s.size =nunits;
}
freep = prevp;
/****************** Blocco aggiunto ************/
size = nbytes;
led = (size % sizeof(unsigned)!=0) ? 1: 0;
k = (unsigned*)(p+1); kk=k; --k;
kk[size/sizeof(unsigned)+ led]=(uns)(p+1);
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 */
{ // ho aggiunto le seguenti 11 righe
dnm = yuyuy + (nunits<NALLOC ? NALLOC: nunits);
dnm = (dnm *8.0)/1024000.0; // tutta la memoria in MB
if(dnm > 13.1 ) G lab90; // se memoria > 13.1MB esci
if((p=morecore(nunits)) == NULL)
{
lab90:;
if(stdout_m!=0 && stdout_m->fd!=(int)IVA_)
P("\nErrore: memoria insufficiente\n");
exit_m(1); // voglio uscire
return NULL; /* non c'e' piu' spazio */
}
yuyuy += (nunits<NALLOC ? NALLOC: nunits);
/* numero di unita' di mem. richieste al sistema */
}
}
}
/*
unsigned verifica_all_m( void )
Ritorna il numero degli elementi;
se il numero degli elementi e' 0 ritorna (unsigned) -1
se errori di out of bound per qualche puntatore ritorna 0
*/
unsigned verifica_all_m( void )
{unsigned *k, *kk, xk, xkk, led;
int j;
/*----------------*/
if( p_p_p_==0 || i_i_i_==0 ) R -1;
F(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) )
{ Ps_m(memo_ , 300, "verifica_all_mMEM_+ p=%p size=%u
p[-1]=%u p[max]=%u n:v=%u:%u",
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) )
{ Ps_m(memo_ , 300, "verifica_all_mMEM_- p=%p size=%u
p[-1]=%u p[max]=%u n:v=%u:%u",
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;
}
}
R i_i_i_;
}
void verifica_all( void )
{if(verifica_all_m( )==0)
{P("Errore nella memoria\n");
if(*memo_ !=0 && *name_ != 0 )
P("memo=%s name=%s\n", memo_, name_ );
}
}
/* unsigned verifica_m( void* pointer, int *jj)
-se pointer==0 ritorna
1 se tutto e' cancellato
2 se tutto e' cancellato tranne il puntatore iniziale
3 altrimenti
-se pointer!=0 ritorna
0 se il vettore puntato da pointer fa parte della lista
1 se tutto e' cancellato
7 se il vettore puntato da pointer non fa parte della lista
8 se il vettore puntato da pointer fa parte della lista
ma ci sono errori di scrittura "out of bounds" 'iniziali'
9 se il vettore puntato da pointer fa parte della lista
ma ci sono errori di scrittura "out of bounds" 'finali'
*/
unsigned verifica_m( void* pointer, int *jj)
{unsigned *k, *kk, xk, xkk, led;
int j;
/*----------------*/
if(jj!=0) *jj=0;
if(pointer==0)
{if( i_i_i_==0 && p_p_p_==0 ) R 1;
else if(i_i_i_==0) R 2;
else R 3;
}
if(p_p_p_==0 ) R 1;
F(j=i_i_i_-1 ; j>=0 ; --j)
if( p_p_p_[j]->p == pointer ) break;
if(j<0) {P("\nverifica_mMEM_0 0x%p indice=%u ", pointer, i_i_i_ );
if(*memo_ && *name_ )
P( "memo=%s name=%s", memo_, name_ );
P("\n");
if(n_i_>2) name_[n_i_ -2]='0';
R 7;
}
k = (unsigned*) pointer; kk=k; --k;
led = (p_p_p_[j]->size % sizeof(unsigned)!=0) ? 1: 0;
*jj=j;
if( (xk=kk[p_p_p_[j]->size/sizeof(unsigned) + led]) !=
(xkk=p_p_p_[j]->piu) )
{ P("\np=0x%p size=%u p[-1]=%u p[max]=%u ", pointer,
p_p_p_[j]->size, *k, xk);
P("verifica_mMEM_+ n:v>%u:%u\n", xk, xkk);
if(n_i_>2) name_[ n_i_ - 2 ]='+';
return 8;
}
if( (xk=*k) != (xkk=p_p_p_[j]->meno) )
{ P("\np=0x%p size=%u p[-1]=%u p[max]=%u ", pointer,
p_p_p_[j]->size, xkk, p_p_p_[j]->piu);
P("verifica_mMEM_- n:v>%u:%u\n", xk, xkk);
if(n_i_>2) name_[n_i_ - 2]='-';
return 9;
}
else R 0;
}
unsigned verifica_p_m( void* pointer)
{int jj; R verifica_m( pointer, &jj);}
static void free_list_m(void)
{W(list_i_!=0)
{--list_i_; free_sys(list_[list_i_]);}
free_sys(list_); list_=0; list_m_=0; freep=NULL;
}
static void free_vettore_m(void)
{int j;
if(p_p_p_==0) { m_m_m_=0; i_i_i_=0; R;}
F(j=0; j<m_m_m_; ++j) // v[0]...v[size]=size+1
free_sys((void*) p_p_p_[j]);
free_sys((void*) p_p_p_);
p_p_p_=0; m_m_m_=0; i_i_i_=0;
}
static void inserisci(void* ap, unsigned jk, int j)
{Header *bp, *p, *r;
static unsigned f_cont=0;
/*-------------------*/
if(jk==0) ++f_cont;
bp = (Header*)ap - 1; /* punta all'header del blocco */
F( r=p=freep; !(bp>p && bp < p->s.ptr); r=p, p=p->s.ptr )
if( p >= p->s.ptr && (bp>p || bp < p->s.ptr) )
break; /* il blocco liberato e'
ad un estremo della lista*/
if(jk) goto label;
/********************************************/
if(j != i_i_i_ - 1)
{p_p_p_[j]->p = p_p_p_[i_i_i_ - 1]->p;
p_p_p_[j]->size = p_p_p_[i_i_i_ - 1]->size;
p_p_p_[j]->meno = p_p_p_[i_i_i_ - 1]->meno;
p_p_p_[j]->piu = p_p_p_[i_i_i_ - 1]->piu;
}
p_p_p_[--i_i_i_]->p =0; p_p_p_[i_i_i_]->size=0;
p_p_p_[i_i_i_]->meno=0; p_p_p_[i_i_i_]->piu =0;
if(m_m_m_>1000 && f_cont%1024==0)
mem_init(i_i_i_+64);
/***********************************************/
label:
if(bp+bp->s.size == p->s.ptr)/*lo unisce al blocco dopo*/
{bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
}
else bp->s.ptr=p->s.ptr;
if(p+p->s.size == bp)/* lo unisce al blocco prima*/
{p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
freep=r; R;
}
else p->s.ptr=bp;
freep = p;
}
void free_all_m(void) {free_vettore_m(); free_list_m();}
/*Non usare free_all_m() ma free_a_i_m se ci sono oggetti
allocati da costruttori e distruttori del c++
(gli oggetti fuori da una qualsiasi procedura finiscono quando si
chiude
l'ultima istruzione del main) */
void free_a_i_mm(void)
{if(i_i_i_==0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag)
P("MEMORIA DINAMICA LIBERATA Tot=%0f Mb\n",
((yuyuy*8.0)/1024000.0) );
}
else if( i_i_i_>=1 && p_p_p_!= 0 )
{if(stdout_m->flag)
P("Vi e' ancora da liberare 0x%p\n", (void*) p_p_p_[0]->p);
}
}
void free_a_i_m(void)
{if(i_i_i_==0 && show_si==0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag)
P("MEMORIA DINAMICA LIBERATA Tot=%.4L Mb\n",
(long double) ((yuyuy*8.0)/1024000.0) );
show_si=1;
}
}
void free_a_r_m(void)
{if(i_i_i_==0)
{free_vettore_m(); free_list_m(); }
else if( i_i_i_>=1 && p_p_p_!= 0 && stdout_m->flag!=0)
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
void free_a_e_m(void)
{if(i_i_i_==0 && p_p_p_!=0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag && p_p_p_==0)
{stato_mem();
P("Memoria libera\n");
}
}
else if( i_i_i_>=1 && p_p_p_!= 0 && stdout_m->flag)
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
/* morecore: chiede al sistema memoria aggiuntiva */
static Header* morecore(unsigned nu)
{char *cp, **p;
Header *up;
unsigned len;
/*-----------------------*/
if(nu<NALLOC) nu=NALLOC;
// P("@@");
cp = (char*) malloc_sys(nu * sizeof(Header));
// P("%u##", nu);
if( cp==0 ) /* non c'e' piu' spazio */
return NULL;
if(list_i_ >= list_m_ )
{len = (list_m_==0 ? 128: 2*list_m_);
if(list_==0) list_ = (char**) malloc_sys(4);
p = (char**) realloc_sys(list_, len * sizeof *p);
if(p==0) {free_sys(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);
return freep;
}
/* se pointer!=0 ritorna la size del pointer
ritorna 0 se il pointer non c'e' */
unsigned get_size_m( void* pointer )
{int j;
/*----------------*/
if(pointer==0 || p_p_p_==0) R 0;
F(j=i_i_i_-1 ; j>=0 ; --j)
if( p_p_p_[j]->p == pointer ) break;
if(j<0) R 0;
R p_p_p_[j]->size;
}
void* realloc_m1(void *p, unsigned nbytes)
{unsigned j, k;
char *p1, *p2=(char*)p;
p1= (char*) malloc_m(nbytes);
if(p1==0) R 0;
k=get_size_m(p);
k = (k<=nbytes? k:nbytes);
F( j=0; j<k; ++j)
p1[j]=p2[j];
free_m(p);
R p1;
}
void* realloc_m(void *p, int nbytes)
{int k;
uns a, r, j, i;
char *p1, *p2;
if(nbytes<0) R 0;
k=get_size_m(p);
if(k<0) R 0;
p1= (char*) malloc_m(nbytes);
if(p1==0) R 0;
i = k<=nbytes? k: nbytes;
a=i/(sizeof(int)); r=i&(sizeof(int)-1);
F(j=0, p2=(char*)p; j<a; ++j)
((int*)p1)[j]=((int*)p2)[j];
F(i=4*j, r+=i; i<r; ++i)
p1=p2;
free_m(p);
R p1;
}
void init_w(const char *nam)
{unsigned i, j;
/*---------------------*/
if(nam==0) R;
if( n_i_ > 2 )
name_[n_i_ - 1]='|';
if( n_i_ >= 1016 ) // 0..14 carattere 15='|'
n_i_=0;
F(i=n_i_, j=0; j<15 && nam[j]!=0; ++i, ++j)
name_=nam[j];
F( ; j< 15; ++i, ++j)
name_=' ';
name_ = '#';
n_i_ += 16;
}
void leggi_mem(void)
{Header *u, *v;
unsigned j;
F( u = freep; u!=0 ; )
{P("|v=%u s=%u|", (unsigned)u / sizeof(Header), u->s.size );
if(u->s.ptr==freep) break;
v=u->s.ptr;
if((u + u->s.size) != v)
{j = (uns)(v-u) - u->s.size;
if(j<123456)
P("%u", j );
else P("#");
}
u=v;
}
}
void stato_mem(void)
{unsigned j;
leggi_mem();
P("\nRAPPORTO MEMORIA DINAMICA. ");
P("Memoria richiesta al sistema=%.4f Mb ", ((yuyuy*8.0)/1024000.0) );
j=verifica_all_m();
if(j!=0 && j!=-1)
{P("%u vettor%c allocat%c con successo\n",
j, j==1?'e':'i', j==1?'o':'i');
if( p_p_p_!= 0 && p_p_p_[0]!=0 )
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
else {if(j==0) {P("Out of bounds "); goto label;}
P("Il sistema non ha vettori da liberare ritornati da
malloc_m\n"); // j==-1
j=verifica_m(0, 0);
if(j==1) P("Sia la base sia il contatore sono NULLI\n");
else if(j==2) P("Il contatore e' nullo ma la base no\n");
else {label: ;
P("Errori nella memoria\n");
if(*memo_ && *name_)
P("memo=%s name=%s\n", memo_, name_ );
// free_vettore_m(); free_list_m();
exit_m(1);
}
}
}
void controlla_m(char* st)
{P("!%s!", st);
if(verifica_all_m()==0)
{if(st) P("ERRORE!");
stato_mem();
}
}
/* free: inserisce in free list il blocco ap */
void free_m(void* ap)
{ int j, k;
/*-------------------*/
if(ap==0) R ;
if(libero_m_)
{if(verifica_all_m()==0)
stato_mem();
}
if(k=verifica_m(ap, &j))
{ if(k==7)
{P("free_m(): ha cercato di liberare un puntatore che
non \n");
P("appartiene a quelli rilasciati da malloc_m: Esco...
\n");
}
else if(k==8 || k==9)
{P("free_m(): ha cercato di liberare un puntatore
\n");
P("in cui \"out of bound\" riscrittura. Esco... \n");
}
stato_mem();
// free_vettore_m(); free_list_m();
exit_m(1);
}
inserisci(ap, 0, j);
}
void stampa_chiamate(void){P("memo=%s name=%s\n", memo_, name_ );}
malloc function that use a nobody student
is better than all yours
How many errors do you see?
Bug1: memory<13MB
Bug2:
it seems do you have to write you own sprintf "Ps_m"
Ps_m(char* out, int len, char* fmt, ...)
that has the len of array in the second arg
#include <windows.h>
#include <winbase.h>
#include <wincon.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <winuser.h>
#include "winb.h"
#define IVA_ INVALID_HANDLE_VALUE
#define P printf
#define W while
#define F for
#define R return
/* MEM_LIMIT e' il limite del numero di diversi puntatori
ritornati da malloc_m */
#define MEM_LIMIT 200000
#define MAX_ARRAYS 255
/*************************CCCCCCC**********************************/
#ifdef __cplusplus
extern "C" {
#endif
void* malloc_sys(int n)
{if(n<0) R 0;
R (void*)LocalAlloc(LMEM_FIXED, n);
}
void free_sys(void* p){ LocalFree(p); }
void* realloc_sys(void *p, int nbytes)
{int k;
uns a, r, j, i;
char *p1, *p2;
if(nbytes<0) R 0;
k=LocalSize(p);
if(k<0) R 0;
p1= (char*) LocalAlloc(LMEM_FIXED, nbytes);
if(p1==0) R 0;
i = k<=nbytes? k: nbytes;
a=i/(sizeof(int)); r=i&(sizeof(int)-1);
F(j=0, p2=(char*)p; j<a; ++j)
((int*)p1)[j]=((int*)p2)[j];
F(i=4*j, r+=i; i<r; ++i)
p1=p2;
LocalFree(p);
R p1;
}
#define NALLOC 1024
// 1024 /* numero minimo di unita' richieste */
// 1024*256*8=1024*1024*2 = 2 mega
static unsigned yuyuy=0;
typedef double Align; /* per allineare alla double */
union header { /* header del blocco */
struct {union header* ptr; /* blocco successivo in free list */
unsigned size; /* dimensione di questo blocco */
}s;
Align x; /* forza l'allineamento dei blocchi */
}; /* sizeof header == 4+4 = 8 */
typedef union header Header;
static Header base; /* lista vuota per iniziare */
static Header *freep=NULL; /* inizio della free list */
static char name_ [ 1100 ] = {0}; /* name_== nome routines
chiamate */
static char memo_ [ 300 ] = {0}; /* stringa ove errori
trovati in memoria */
static int n_i_ = 0 ;
int libero_m_ = 0 ; /* libero_m_==1 controllo tutti i
vettori a
ogni chiamate di free(); serve insieme a name_ per individuare le
routines che
sovrascrivono la memoria che non hanno (e.g. if(libero_m_)
init_w("nome_routines") */
typedef struct {
void *p;
unsigned size;
unsigned piu;
unsigned meno;
}vettore_array;
static vettore_array **p_p_p_=0; /* lista di struct di puntatori
ritornati da malloc_m */
static int i_i_i_=0; /* attuale indice nella lista */
static int m_m_m_=0; /* massimo indice nella lista */
static char **list_ =0; /* lista dei vettori richiesti al
sys */
static int list_i_=0;
static int list_m_=0;
static int show_si =0;
static int mem_init(int siz)
{vettore_array **pp;
int j;
/*---------------------*/
//P("p_p_p_=%p i_i_i_==%u siz=%u ", (void*) p_p_p_, i_i_i_, siz );
if(siz<0) R 0;
if(p_p_p_==0)
{pp= (vettore_array**) malloc_sys( (siz+1) * sizeof *pp );
if(pp==0) R 0;
F( j=0; j<siz; ++j)
{pp[j]= (vettore_array*) malloc_sys(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
F( --j ; j!=0 ; --j)
free_sys( (void*) pp[j] );
free_sys((void*) pp[0]); free_sys((void*) pp); R 0;
}
}
show_si=0;
}
else { if(siz==m_m_m_) R 1;
else if(siz < m_m_m_) /* dovrebbe distruggere la
memoria eccessiva */
{ if(siz<=i_i_i_) R 1; /* la 1024ma volta che viene
chiamato free_m()*/
F(j=siz; j<m_m_m_; ++j) // v[0]...v[size]=size+1
free_sys((void*) p_p_p_[j]);
pp=(vettore_array**) realloc_sys(p_p_p_, (siz + 1) *
sizeof *pp );
if(pp==0) {P("Fallimento realloc\n"); m_m_m_ = siz; R
1;}
/* ritorna senza cambiare niente */
goto label;
}
pp= (vettore_array**) realloc_sys( (void*) p_p_p_, (siz + 1)
* sizeof *pp);
if(pp==0) {P("Fallimento realloc\n"); R 0;}
if( siz > i_i_i_)
{ F( j=i_i_i_; j<siz; ++j)
{
pp[j]= (vettore_array*) malloc_sys(sizeof(vettore_array));
if(pp[j]==0)
{if(j!=0)
F( --j ; j!=0 ; --j)
free_sys( (void*) pp[j] );
free_sys((void*) pp[0]); R 0;
}
}
}
}
label: ;
m_m_m_ = siz; p_p_p_=pp; R 1;
}
/* malloc_m: allocatore di memoria */
void* malloc_m(unsigned nbytes)
{Header *p, *prevp;
unsigned nunits, *k, *kk, led, size;
double dnm;
Header* morecore(unsigned);
unsigned verifica_all_m( void );
void stato_mem(void);
/*-------------------------------*/
if(libero_m_)
{if(verifica_all_m()==0) stato_mem();}
if(i_i_i_>MEM_LIMIT || nbytes==0 ) R 0;
if(i_i_i_>=m_m_m_)
{if(mem_init( i_i_i_ + MAX_ARRAYS ) == 0) R 0;}
nunits = nbytes + sizeof(Header);
nunits = nunits/sizeof(Header) +
(( nunits%sizeof(Header) >sizeof(unsigned) ) ? 1: 0) + 1;
if((prevp=freep)==NULL) /* non esiste la 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) /* spazio insufficiente */
{if(p->s.size==nunits) /* esattamente */
{prevp->s.ptr = p->s.ptr;}
else /* alloca la parte finale */
{p->s.size -= nunits;
p += p->s.size;
p->s.size =nunits;
}
freep = prevp;
/****************** Blocco aggiunto ************/
size = nbytes;
led = (size % sizeof(unsigned)!=0) ? 1: 0;
k = (unsigned*)(p+1); kk=k; --k;
kk[size/sizeof(unsigned)+ led]=(uns)(p+1);
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 */
{ // ho aggiunto le seguenti 11 righe
dnm = yuyuy + (nunits<NALLOC ? NALLOC: nunits);
dnm = (dnm *8.0)/1024000.0; // tutta la memoria in MB
if(dnm > 13.1 ) G lab90; // se memoria > 13.1MB esci
if((p=morecore(nunits)) == NULL)
{
lab90:;
if(stdout_m!=0 && stdout_m->fd!=(int)IVA_)
P("\nErrore: memoria insufficiente\n");
exit_m(1); // voglio uscire
return NULL; /* non c'e' piu' spazio */
}
yuyuy += (nunits<NALLOC ? NALLOC: nunits);
/* numero di unita' di mem. richieste al sistema */
}
}
}
/*
unsigned verifica_all_m( void )
Ritorna il numero degli elementi;
se il numero degli elementi e' 0 ritorna (unsigned) -1
se errori di out of bound per qualche puntatore ritorna 0
*/
unsigned verifica_all_m( void )
{unsigned *k, *kk, xk, xkk, led;
int j;
/*----------------*/
if( p_p_p_==0 || i_i_i_==0 ) R -1;
F(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) )
{ Ps_m(memo_ , 300, "verifica_all_mMEM_+ p=%p size=%u
p[-1]=%u p[max]=%u n:v=%u:%u",
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) )
{ Ps_m(memo_ , 300, "verifica_all_mMEM_- p=%p size=%u
p[-1]=%u p[max]=%u n:v=%u:%u",
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;
}
}
R i_i_i_;
}
void verifica_all( void )
{if(verifica_all_m( )==0)
{P("Errore nella memoria\n");
if(*memo_ !=0 && *name_ != 0 )
P("memo=%s name=%s\n", memo_, name_ );
}
}
/* unsigned verifica_m( void* pointer, int *jj)
-se pointer==0 ritorna
1 se tutto e' cancellato
2 se tutto e' cancellato tranne il puntatore iniziale
3 altrimenti
-se pointer!=0 ritorna
0 se il vettore puntato da pointer fa parte della lista
1 se tutto e' cancellato
7 se il vettore puntato da pointer non fa parte della lista
8 se il vettore puntato da pointer fa parte della lista
ma ci sono errori di scrittura "out of bounds" 'iniziali'
9 se il vettore puntato da pointer fa parte della lista
ma ci sono errori di scrittura "out of bounds" 'finali'
*/
unsigned verifica_m( void* pointer, int *jj)
{unsigned *k, *kk, xk, xkk, led;
int j;
/*----------------*/
if(jj!=0) *jj=0;
if(pointer==0)
{if( i_i_i_==0 && p_p_p_==0 ) R 1;
else if(i_i_i_==0) R 2;
else R 3;
}
if(p_p_p_==0 ) R 1;
F(j=i_i_i_-1 ; j>=0 ; --j)
if( p_p_p_[j]->p == pointer ) break;
if(j<0) {P("\nverifica_mMEM_0 0x%p indice=%u ", pointer, i_i_i_ );
if(*memo_ && *name_ )
P( "memo=%s name=%s", memo_, name_ );
P("\n");
if(n_i_>2) name_[n_i_ -2]='0';
R 7;
}
k = (unsigned*) pointer; kk=k; --k;
led = (p_p_p_[j]->size % sizeof(unsigned)!=0) ? 1: 0;
*jj=j;
if( (xk=kk[p_p_p_[j]->size/sizeof(unsigned) + led]) !=
(xkk=p_p_p_[j]->piu) )
{ P("\np=0x%p size=%u p[-1]=%u p[max]=%u ", pointer,
p_p_p_[j]->size, *k, xk);
P("verifica_mMEM_+ n:v>%u:%u\n", xk, xkk);
if(n_i_>2) name_[ n_i_ - 2 ]='+';
return 8;
}
if( (xk=*k) != (xkk=p_p_p_[j]->meno) )
{ P("\np=0x%p size=%u p[-1]=%u p[max]=%u ", pointer,
p_p_p_[j]->size, xkk, p_p_p_[j]->piu);
P("verifica_mMEM_- n:v>%u:%u\n", xk, xkk);
if(n_i_>2) name_[n_i_ - 2]='-';
return 9;
}
else R 0;
}
unsigned verifica_p_m( void* pointer)
{int jj; R verifica_m( pointer, &jj);}
static void free_list_m(void)
{W(list_i_!=0)
{--list_i_; free_sys(list_[list_i_]);}
free_sys(list_); list_=0; list_m_=0; freep=NULL;
}
static void free_vettore_m(void)
{int j;
if(p_p_p_==0) { m_m_m_=0; i_i_i_=0; R;}
F(j=0; j<m_m_m_; ++j) // v[0]...v[size]=size+1
free_sys((void*) p_p_p_[j]);
free_sys((void*) p_p_p_);
p_p_p_=0; m_m_m_=0; i_i_i_=0;
}
static void inserisci(void* ap, unsigned jk, int j)
{Header *bp, *p, *r;
static unsigned f_cont=0;
/*-------------------*/
if(jk==0) ++f_cont;
bp = (Header*)ap - 1; /* punta all'header del blocco */
F( r=p=freep; !(bp>p && bp < p->s.ptr); r=p, p=p->s.ptr )
if( p >= p->s.ptr && (bp>p || bp < p->s.ptr) )
break; /* il blocco liberato e'
ad un estremo della lista*/
if(jk) goto label;
/********************************************/
if(j != i_i_i_ - 1)
{p_p_p_[j]->p = p_p_p_[i_i_i_ - 1]->p;
p_p_p_[j]->size = p_p_p_[i_i_i_ - 1]->size;
p_p_p_[j]->meno = p_p_p_[i_i_i_ - 1]->meno;
p_p_p_[j]->piu = p_p_p_[i_i_i_ - 1]->piu;
}
p_p_p_[--i_i_i_]->p =0; p_p_p_[i_i_i_]->size=0;
p_p_p_[i_i_i_]->meno=0; p_p_p_[i_i_i_]->piu =0;
if(m_m_m_>1000 && f_cont%1024==0)
mem_init(i_i_i_+64);
/***********************************************/
label:
if(bp+bp->s.size == p->s.ptr)/*lo unisce al blocco dopo*/
{bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
}
else bp->s.ptr=p->s.ptr;
if(p+p->s.size == bp)/* lo unisce al blocco prima*/
{p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
freep=r; R;
}
else p->s.ptr=bp;
freep = p;
}
void free_all_m(void) {free_vettore_m(); free_list_m();}
/*Non usare free_all_m() ma free_a_i_m se ci sono oggetti
allocati da costruttori e distruttori del c++
(gli oggetti fuori da una qualsiasi procedura finiscono quando si
chiude
l'ultima istruzione del main) */
void free_a_i_mm(void)
{if(i_i_i_==0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag)
P("MEMORIA DINAMICA LIBERATA Tot=%0f Mb\n",
((yuyuy*8.0)/1024000.0) );
}
else if( i_i_i_>=1 && p_p_p_!= 0 )
{if(stdout_m->flag)
P("Vi e' ancora da liberare 0x%p\n", (void*) p_p_p_[0]->p);
}
}
void free_a_i_m(void)
{if(i_i_i_==0 && show_si==0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag)
P("MEMORIA DINAMICA LIBERATA Tot=%.4L Mb\n",
(long double) ((yuyuy*8.0)/1024000.0) );
show_si=1;
}
}
void free_a_r_m(void)
{if(i_i_i_==0)
{free_vettore_m(); free_list_m(); }
else if( i_i_i_>=1 && p_p_p_!= 0 && stdout_m->flag!=0)
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
void free_a_e_m(void)
{if(i_i_i_==0 && p_p_p_!=0)
{free_vettore_m(); free_list_m();
if(stdout_m->flag && p_p_p_==0)
{stato_mem();
P("Memoria libera\n");
}
}
else if( i_i_i_>=1 && p_p_p_!= 0 && stdout_m->flag)
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
/* morecore: chiede al sistema memoria aggiuntiva */
static Header* morecore(unsigned nu)
{char *cp, **p;
Header *up;
unsigned len;
/*-----------------------*/
if(nu<NALLOC) nu=NALLOC;
// P("@@");
cp = (char*) malloc_sys(nu * sizeof(Header));
// P("%u##", nu);
if( cp==0 ) /* non c'e' piu' spazio */
return NULL;
if(list_i_ >= list_m_ )
{len = (list_m_==0 ? 128: 2*list_m_);
if(list_==0) list_ = (char**) malloc_sys(4);
p = (char**) realloc_sys(list_, len * sizeof *p);
if(p==0) {free_sys(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);
return freep;
}
/* se pointer!=0 ritorna la size del pointer
ritorna 0 se il pointer non c'e' */
unsigned get_size_m( void* pointer )
{int j;
/*----------------*/
if(pointer==0 || p_p_p_==0) R 0;
F(j=i_i_i_-1 ; j>=0 ; --j)
if( p_p_p_[j]->p == pointer ) break;
if(j<0) R 0;
R p_p_p_[j]->size;
}
void* realloc_m1(void *p, unsigned nbytes)
{unsigned j, k;
char *p1, *p2=(char*)p;
p1= (char*) malloc_m(nbytes);
if(p1==0) R 0;
k=get_size_m(p);
k = (k<=nbytes? k:nbytes);
F( j=0; j<k; ++j)
p1[j]=p2[j];
free_m(p);
R p1;
}
void* realloc_m(void *p, int nbytes)
{int k;
uns a, r, j, i;
char *p1, *p2;
if(nbytes<0) R 0;
k=get_size_m(p);
if(k<0) R 0;
p1= (char*) malloc_m(nbytes);
if(p1==0) R 0;
i = k<=nbytes? k: nbytes;
a=i/(sizeof(int)); r=i&(sizeof(int)-1);
F(j=0, p2=(char*)p; j<a; ++j)
((int*)p1)[j]=((int*)p2)[j];
F(i=4*j, r+=i; i<r; ++i)
p1=p2;
free_m(p);
R p1;
}
void init_w(const char *nam)
{unsigned i, j;
/*---------------------*/
if(nam==0) R;
if( n_i_ > 2 )
name_[n_i_ - 1]='|';
if( n_i_ >= 1016 ) // 0..14 carattere 15='|'
n_i_=0;
F(i=n_i_, j=0; j<15 && nam[j]!=0; ++i, ++j)
name_=nam[j];
F( ; j< 15; ++i, ++j)
name_=' ';
name_ = '#';
n_i_ += 16;
}
void leggi_mem(void)
{Header *u, *v;
unsigned j;
F( u = freep; u!=0 ; )
{P("|v=%u s=%u|", (unsigned)u / sizeof(Header), u->s.size );
if(u->s.ptr==freep) break;
v=u->s.ptr;
if((u + u->s.size) != v)
{j = (uns)(v-u) - u->s.size;
if(j<123456)
P("%u", j );
else P("#");
}
u=v;
}
}
void stato_mem(void)
{unsigned j;
leggi_mem();
P("\nRAPPORTO MEMORIA DINAMICA. ");
P("Memoria richiesta al sistema=%.4f Mb ", ((yuyuy*8.0)/1024000.0) );
j=verifica_all_m();
if(j!=0 && j!=-1)
{P("%u vettor%c allocat%c con successo\n",
j, j==1?'e':'i', j==1?'o':'i');
if( p_p_p_!= 0 && p_p_p_[0]!=0 )
{P("Vi e' ancora da liberare 0x%p\n", (void*)
p_p_p_[0]->p);}
}
else {if(j==0) {P("Out of bounds "); goto label;}
P("Il sistema non ha vettori da liberare ritornati da
malloc_m\n"); // j==-1
j=verifica_m(0, 0);
if(j==1) P("Sia la base sia il contatore sono NULLI\n");
else if(j==2) P("Il contatore e' nullo ma la base no\n");
else {label: ;
P("Errori nella memoria\n");
if(*memo_ && *name_)
P("memo=%s name=%s\n", memo_, name_ );
// free_vettore_m(); free_list_m();
exit_m(1);
}
}
}
void controlla_m(char* st)
{P("!%s!", st);
if(verifica_all_m()==0)
{if(st) P("ERRORE!");
stato_mem();
}
}
/* free: inserisce in free list il blocco ap */
void free_m(void* ap)
{ int j, k;
/*-------------------*/
if(ap==0) R ;
if(libero_m_)
{if(verifica_all_m()==0)
stato_mem();
}
if(k=verifica_m(ap, &j))
{ if(k==7)
{P("free_m(): ha cercato di liberare un puntatore che
non \n");
P("appartiene a quelli rilasciati da malloc_m: Esco...
\n");
}
else if(k==8 || k==9)
{P("free_m(): ha cercato di liberare un puntatore
\n");
P("in cui \"out of bound\" riscrittura. Esco... \n");
}
stato_mem();
// free_vettore_m(); free_list_m();
exit_m(1);
}
inserisci(ap, 0, j);
}
void stampa_chiamate(void){P("memo=%s name=%s\n", memo_, name_ );}