Newsgroup: it.comp.programmare.win32
Titolo: Problemi di memoria

Salve,
ho scritto una piccola classe che crea delle variabili dinamiche durante 
l'uso, e spesso le alloca e dealloca continuamente all'interno di un ciclo.
Il codice potrebbe essere riassunto cosě:
inizio ciclo
	0 Controlla se la memoria non č allocata
	1 Se č allocata deallocala
	2 Alloca memoria
fine ciclo
La prima volta tutto ok, la seconda volta rileva che l'area di memoria č 
deallocata ma la deallocazione causa l'errore :
HEAP[FinalMapping.exe]: Heap block at 003237B0 modified at 00324638 past 
requested size of e80
[visibile nella finestra di debug]
I modelli di memoria utilizzata dai due programmi č il medesimo [Debug 
Multithreaded DLL].
Ho controllato gli accessi a quel vettore ma non ne vengono effettuati !
Perchč crasha ??
Grazie

 
Dimenticavo, la dialog con il messaggio di errore dice :
Damage after normal block(#55) at indirizzo
[quel messaggio riportato sopra è nella finestra di debug]

 effettuati !
Allora stai probabilmente cercando di deallocare blocchi già deallocati.
Azzeri tutti i ptr dopo aver deallocato la memoria alla quale puntano?
Kiuhnm


Si...

Senza vedere il codice è difficile capire qual è l'errore.
Kiuhnm


Mi hai preceduto di un nulla... stavo per dire la stessa cosa!
Dario


Ecco il corpo del metodo che viene invocato per distruggere il vettore:
if (Piani[Source]._area != NULL)
		delete [] Piani[Source]._area;
	Piani[Source]._area = NULL;
	Piani[Source].Height = 0;
	Piani[Source].Width = 0;
Piani[] è un vettore di 4 elementi, _area è un puntatore ad intero 
allocato in una funzione con qualcosa tipo:
_area = new int[K];
Height e Width sono informazioni su come interpretare la matrice _area.
Ecco il codice che alloca :
in ingresso X, Y , Source
	_ASSERT (Source == 1 || Source == 2 || Source == 3);
	_ASSERT (X>0 && Y>0);
 
	int counter = 0;
	if (Piani[Source].Height != 0)		<- Uso l'altezza della 								matrice 
per verificare 								che sia allocata o meno,  						ma posso usare 
anche 								controlli su _area
		DestroyRotation(Source);
	Piani[Source]._area = new Point[X * Y];
	if (Piani[Source]._area != NULL)
	{
		while ( counter < X*Y )
		{
		  Piani[Source]._area[counter++].Set(-1000,-1000,false);
		}
		Piani[Source].Height = Y;
		Piani[Source].Width = X;
 
		return true;
	}
	else
		return false;
}
Queste vengono chiamate all'interno di un ciclo.
Intuizioni ?


_area è un puntatore di tipo Point [ fatto da 2 interi ]

 wrote in message
news:3E245079...@libero.it...

Come fai a fare il passo 0?
Come fai a dire che la memoria e' gia' allocata?
Inizializzi tutti i puntatori a NULL e poi controlli se il puntatore e'
diverso da NULL per dire che la memoria e' allocata?
Maurus
p.s.
posta un po' di codice


Uh....una cosa interessante.
Nel fare debug ho controllato più volte se cambiava l'indirizzo del 
puntatore durante l'esecuzione di codice apparentemente slacciato da 
questo vettore, e non succedeva.
Adesso ho fatto una prova ed è successa una cosa analoga ma in un altro 
punto del codice e il puntatore che (almeno apparentemente) non riesce 
ad essere allocato ha l'indirizzo UGUALE a quello delle precedenti prove 
: 0x003237dc !
Cioè adesso un certo puntatore non è stato allocato ed aveva 
quest'indirizzo; quello delle prove precedenti (in un'ALTRA parte del 
codice) aveva lo stesso indirizzo !
E' come se fosse concessa durante l'allocazione una locazione illecita.
A me 'sta cosa sembra assurda, ma aspetto delucidazioni.


Ho postato un pň di codice in altre risposte...

 _area č un puntatore di tipo Point [ fatto da 2 interi ]
Se lo allochi come hai detto in precedenza (_area = new int[K]), non vedo
problemi (nel codice postato).
Probabilmente, da qualche parte nel codice (non postato), scrivi sull'heap
in zone non allocate (anche un elemento oltre lo spazio allocato).
Kiuhnm

 illecita. A me 'sta cosa sembra assurda, ma aspetto delucidazioni.
Solitamente (e penso valga anche per Windows) il gestore dell'heap unisce i
dati utenti a quelli utilizzati per gestire l'heap stesso.
----    <--- block_start
prev
next
----    <--- user_data_start
.
.
.
----
Tutte le volte che allochi n bytes, il gestore dell'heap allocherà
n+HEAP_DATA_SIZE bytes e ritornerà l'indirizzo user_data_start. Al momento
della deallocazione ricaverà block_start partendo da user_data_start
(l'unico che ti è stato dato dalla new) e poi userà prev e next per fare le
proprie operazioni sulla lista linkata.
Naturalmente può anche usare un albero, una skip-list, uno
skip-tree...insomma sono affari suoi: il prob. è che i suoi dati sono in
mezzo ai tuoi.
Se scrivi fuori dalla zona allocata succede un casino!
A volte basta una stringa senza lo zero finale...
Kiuhnm

 >     Piani[Source].Width = 0;
In sostanza tu prima controlli che _area sia diversa da NULL per fare la
delete e poi annulli _area.
Ma la prima volta che fai il controllo sei sicuro che _area sia NULL ?
Lo hai messo a NULL nel costruttore di Piani?
Altrimenti la prima volta che passi la' _area potrebbe essere diverso da
NULL anche se non avevi allocato memoria e fai la delete.
Idem dicasi per il controllo che fai su Height per fare la
DestroyRotation(Source);
E in pratica che fa quest'ultima funzione? Distrugge il piano relativo a
Source ok , ma come lo fa?
Maurus

 Maurus
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Se non vuoi distribuire l'intero codice (mi sembra legittimo, ci mancherebbe
altro!), cerca di ridurlo al minimo in modo che sia compilabile e che
contenga l'errore. A questo punto dopo che l'avrai postato potremo veramente
darti una mano.
Con spezzoni di codice si brancola nel buio. Di solito ci sono errori
evidenti, ma nel tuo caso non mi sembra proprio.
Kiuhnm


Aspetta non ho capito questa cosa:
tu fai gia' questa stessa delete sopra dove fai il test sul NULL e poi la
ripeti nella DestroyRotation?
Non sara' proprio li' allora il problema?
Maurus

 Kiuhnm
I problemi sono 2 (non avrei ostacoli a fornire l'intero codice
normalmente), ma sono 19 classi, 79 file caricati da progetto Win32 MFC.
Ci vorrebbe tempo per l'adattamento, e siccome trattasi della mia tesi,
non ne ho.
La vedrete in rete a marzo, se riuscirò a finirla... ;)
Ho comunque verificato che in quegli array io inserisco elementi che hanno
la caratteristica di avere, per ogni x
abs(s) <= 8
Ho assertato ciò ( _ASSERT() )è non ottengo errori, il codice non crasha
in corrispondenza degli assert, il fatto è che se vado a stampare ottengo
dei valori INACCETTABILI su una piccola parte di elementi dell'array.
Giuro che non tocco gli array se non in quel punto....ma chiaramente ora
sono partito con una sessione di debug nuova di pacca !


 ora sono partito con una sessione di debug nuova di pacca !
L'errore non č lě, ma da qualche altre parte. Per modificare l'array B non č
indispensabile fare riferimento a B: č possibilissimo fuoriuscire da un
altro oggetto allocato sullo stesso stack.
Devi controllare l'accesso a tutti gli oggetti allocati.
Se hai il Softice (o il TRW) puoi trovare l'errore mettendo dei breakpoint
(solo scrittura) sulla memoria (BPM W).
Comunque mi sorge un dubbio: hai sincronizzato l'accesso alle strutture
condivise tra piů thread in modo corretto???
Kiuhnm

 fuoriuscire da un altro oggetto allocato sullo stesso stack.
Mi correggo: *heap*
Kiuhnm