Torna indietro   Hardware Upgrade Forum > Software > Programmazione

WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
Abbiamo provato la beta di World of Warcraft: Forever, il Classic+ di Blizzard in arrivo il 4 novembre: la nuova razza Skyborne restituisce la sensazione di un gioco nuovo, ma le zone storiche conservano la noia divertita di Classic. Classi ribilanciate, sciamani anche nell'Alleanza e un motore grafico che in 4K gira bene anche su una RTX 3070. Cosa cambia in Forever? La risposta nell'articolo
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra abbina per la prima volta un pannello AMOLED alla tecnologia NXTPAPER con finitura opaca, affiancandoci una fotocamera periscopica da 50 MP con zoom ottico 3x, il SoC Dimensity 7400 Elite e una batteria da 5.800 mAh. Nella prova sul campo emergono luminosità di picco molto elevata, comparto fotografico solido per la fascia di prezzo e autonomia nella media, a fronte di velocità di scrittura dello storage piuttosto contenute
HUAWEI MatePad Air recensione: OLED opaco e tastiera dedicata per lavorare meglio
HUAWEI MatePad Air recensione: OLED opaco e tastiera dedicata per lavorare meglio
HUAWEI MatePad Air combina diverse carte molto interessanti: un OLED PaperMatte da 12 pollici, un corpo sottile e una tastiera molto comoda. Durante la prova abbiamo apprezzato fluidità, audio e comfort visivo, mentre i test hanno chiarito pregi e qualche limite nelle prestazioni. L'autonomia ha convinto anche nell'uso intermittente; la scelta passa dalla compatibilità delle proprie app e dal valore del pacchetto con accessori, proposto a 749 euro
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-02-2010, 19:17   #1
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
[c++] Valgrind rileva diversi errori di scrittura

Sto realizzando una classe che rappresenta una matrice templata. Ormai sono a buon punto, ma eseguendo valgrind mi accorgo che ci sono un pò di errori (nessun memory leak per ora). Provando il copy constructor ricevo i seguenti errori:
Invalid write of size 4
==2410== at 0x4010C4: miamatrice<int>::miamatrice(miamatrice<int> const&) (in /media/Storage/Progetto c++/mymatrix2/a.out)
==2410== by 0x400CB6: main (in /media/Storage/Progetto c++/mymatrix2/a.out)
==2410== Address 0x59441f4 is 0 bytes after a block of size 4 alloc'd
==2410== at 0x4C2596C: operator new(unsigned long) (vg_replace_malloc.c:220)
==2410== by 0x40104C: miamatrice<int>::miamatrice(miamatrice<int> const&) (in /media/Storage/Progetto c++/mymatrix2/a.out)
==2410== by 0x400CB6: main (in /media/Storage/Progetto c++/mymatrix2/a.out)

La classe è così definita:
Codice:
	miamatrice(const miamatrice &other) {                
		nr_=other.nr_;
		nc_=other.nc_;
		m_=new T*[nr_];
	
		
		for (int righe=0; righe<nr_; ++righe)
			{
	                  m_[righe]=new T(nc_);
			  for (int colonne=0; colonne < nc_; ++colonne)
				{
					m_[righe][colonne]=other.m_[righe][colonne];
					
				}
			}
	
		}
dati privati:
T** m_;
unsigned int nr_;
unsigned int nc_;

e costruttore utilizzato per costruire la prima delle due matrici:
Codice:
	miamatrice(unsigned int nr, unsigned int nc){            
		nr_=nr;                                              
		nc_=nc;
		m_=new T*[nr];
		for (int i=0;i<nr;++i) m_[i]=new T[nc];
	}
Mi sembra non ci siano altri metodi che possano causare questi errori. Che cosa genere questa invalid write? a me sembra di ciclare correttamente la matrice!
Di errori ne ho molti altri cominciare a risolvere questo sarebbe un buon inizio

Ultima modifica di cionci : 08-02-2010 alle 19:41.
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 08-02-2010, 19:42   #2
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
m_[righe]=new T(nc_);

forse

m_[righe]=new T[nc_];
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 10:16   #3
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
è giusto, non so perchè vedendo dei vecchi esempi mi è venuto da mettere con le parentesi tonde. Sono incappato in un problema più misterioso però. Se creo una matrice specificando le dimensioni ma non la inizializzo e la stampo non stampa una matrice di tutti 0, ma alcuni 0 e alcuni numeri "casuali". La cosa strana è che se dopo questa matrice ne creo un'altra con lo stesso procedimento questa sarà di tutti 0. Il costruttore che accetta le lunghezze in ingresso l'ho messo nel post di prima, cosa posso aver sbagliato?
Grazie per l'aiuto
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 10:25   #4
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
E' normale. L'allocazione non azzera i valori memoria.
Per la seconda volta, probabilmente la matrice viene allocata nella stessa posizione in cui prima c'erano tutti zero (magari proprio perché avevi inizializzato la matrice precedente con tutti zero).
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 15:35   #5
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
E' normale. L'allocazione non azzera i valori memoria.
Per la seconda volta, probabilmente la matrice viene allocata nella stessa posizione in cui prima c'erano tutti zero (magari proprio perché avevi inizializzato la matrice precedente con tutti zero).
Grazie allora ho fatto giusto! Ma i problemi non finiscono mai
Ho definito l'operatore ++ , e provando a ciclarlo nel main effettivamente stampa tutti i valori correttamente, ma dopo aver beccato l'ultimo elemento valgrind mi rivela un errore di invalid read! Non credo che il for nel main vada oltre la dimensione della matrice, infatti se lo ciclo una volta di meno mi stampa tutti gli elementi tranne uno e non dà nessun errore
questa è la funzione di incremento dell' operatore:

iterator operator++(int) {
iterator(*this);


if (act_c >= colonne-1){
act_c=0;
act_r++;
ptr=&(supporto[act_r][act_c]);
}
else {
if (act_r < righe){
act_c++;
ptr=&(supporto[act_r][act_c]);
}
}
return *this;

}

e questo è il ciclo nel main che si occupa di stamparlo:

for(int i=0; i<A.getRows()* A.getColumns(); i++){
cout<<*ita<<endl;
++ita;
}

cosa può generare questo invalid read?

Comunque grazie mille per le dritte, sono state di grande aiuto
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 16:12   #6
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
f (act_c >= colonne){

O più semplicemente:

counter++;

ptr=&(supporto[counter / righe][counter % colonne];
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 17:14   #7
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
f (act_c >= colonne){

O più semplicemente:

counter++;

ptr=&(supporto[counter / righe][counter % colonne];
il secondo metodo che mi hai consigliato mi sembra molto meglio del primo (meno oneroso e più semplice) ma purtroppo gli errori sono rimasti.
fare invece act_c>=colonne non va bene perchè se le colonne sono 6 act_c deve andare da 0 a 5.
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 17:17   #8
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Se rimangono allora il problema è altrove, prova a fare un po' di debugging condizionale
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-02-2010, 18:15   #9
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
Se rimangono allora il problema è altrove, prova a fare un po' di debugging condizionale
ho risolto il problema era nel main
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 07:42   #10
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da abestos Guarda i messaggi
ho risolto il problema era nel main
Era l'ultimo ++ dell'iteratore ? In effetti ne fa uno in più.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 13:18   #11
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
Era l'ultimo ++ dell'iteratore ? In effetti ne fa uno in più.
si esatto, ho invertito l'ordine delle due istruzioni nel ciclo e ho messo la prima stampa prima del ciclo
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 16:11   #12
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Allora, sto affrontando l'end dell'iteratore. Ho capito che devo puntare fuori dalla matrice per esempio il primo elemento (quindi prima colonna) di una riga oltre la matrice.

iterator end() {

T* ptr;
return ptr;

}

il problema è che non so che tipo di valore ritornare nel metodo end, perchè dando un'occhiata ad alcuni testi mi era sembrato che fosse possibile ritornare un puntatore al dato ma non ci sono riuscito. Considerando che il mio begin è questo:

iterator begin() {



return iterator(m_,nr_ , nc_);

}

ovvero il begin chiama il costruttore di iterator e gli dice di creare una matrice con nr_ righe e nc_colonne. Non potrei fare lo stesso nel metodo end, perchè quello è un costruttore che crea un nuovo iteratore che punta alla prima cella della matrice. Cosa posso fare allora?
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 18:59   #13
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
come non detto dovrei aver fatto l'end dell'iterator. Mi sembra che l'end funzioni bene poichè se faccio un for o un while il ciclo termina correttamente però chiamare l'end genera un invalid read. Ecco come ho definito l'end:

iterator end() {
return iterator(m_,nr_,nc_,nr_,0);

}

in questo modo l'end chiama il costruttore che crea un iterator che punta una riga dopo l'ultima riga della matrice e alla cella zero. ecco il costruttore:

iterator(T** mat, unsigned int rows, unsigned int cols, unsigned int it_rows, unsigned int it_cols){

righe=rows;

colonne=cols;

act_r=it_rows;

act_c=it_cols;

supporto=mat;

ptr=&mat[act_r][act_c];



}

cosa c'è di sbagliato?
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 19:02   #14
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
ptr=&mat[act_r][act_c];

Devi accedere alla matrice solo nel momento in cui usi l'operatore * o ->, ptr te lo devi calcolare solo in quel momento.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 22:55   #15
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
ptr=&mat[act_r][act_c];

Devi accedere alla matrice solo nel momento in cui usi l'operatore * o ->, ptr te lo devi calcolare solo in quel momento.
Dici quindi che l'assegnamento ptr=&supporto[act_r][act_c] dovrebbe andare solo nell operatore * o -> ( e in ++ ??) ? in questo modo però quando ciclo l'iteratore non trova mai che iteratore == matrice.end

Questo perchè matrice.end non va ad aggiornare il puntatore, visto che l'assegnamento è rimasto solo negli operatori sopra citati
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 08:49   #16
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da abestos Guarda i messaggi
Dici quindi che l'assegnamento ptr=&supporto[act_r][act_c] dovrebbe andare solo nell operatore * o -> ( e in ++ ??) ? in questo modo però quando ciclo l'iteratore non trova mai che iteratore == matrice.end
Basta non confrontare il puntatore, ma solamente gli indici

Come nell'esempio che ti ho fatto prima...usa solamente un contatore. end() semplicemente lo inizializzerà a righe*colonne.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 10:10   #17
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Quote:
Originariamente inviato da cionci Guarda i messaggi
Basta non confrontare il puntatore, ma solamente gli indici

Come nell'esempio che ti ho fatto prima...usa solamente un contatore. end() semplicemente lo inizializzerà a righe*colonne.
stai dicendo che nell'operatore di confronto invece che confrontare i puntatori devo confrontare solo gli indici? in questo modo se due iteratori diversi puntano a matrici diverse ma sono casualmente allo stesso numero di righe e colonne l'operatore di uguaglianza ci casca
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 10:25   #18
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Questo lo puoi evitare andando a confrontare l'indirizzo di matrice[0][0].
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 15:32   #19
abestos
Member
 
Iscritto dal: Oct 2004
Città: Monza (MI)
Messaggi: 46
Grazie ai tuoi preziosi consigli dovrei aver risolto l'iteratore. Stavo cominciando a vedere un pò di eccezioni e per prima cosa ho pensato di gestire le eccezioni che possono scaturire dal copy constructor. L'ho definita così:

miamatrice(const miamatrice &other) {

nr_=other.getRows();

nc_=other.nc_;

m_=new T*[nr_];

int protettore;

try{
protettore=0;

for (int righe=0; righe<nr_; ++righe)

{
m_[righe]=new T[nc_];

protettore++;
for (int colonne=0; colonne < nc_; ++colonne)

{

m_[righe][colonne]=other.m_[righe][colonne];



}

}
} catch (std::exception& e)
{
for(int i=0; i<=protettore; i++)
delete[] m_[i];
throw;
}

}

Il problema è che oltre a non sapere se così va bene non so neanche come testarlo. Come posso creare un test che lanci un eccezione dal costruttore di copia?
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 15:45   #20
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
L'unica eccezione che può venire fuori lì è quella nella new:

std::bad_alloc

Secondo me è una di quelle eccezioni che puoi lasciare ingestita o al limite controllarla a livelli più alti. Questo perché è talmente grave che pregiudica l'operatività sia del programma, ma anche solitamente del sistema. Quindi il tuo programma termina comunque. Certo sarebbe bene correre ai ripari, ma come fai senza poter allocare nuova memoria ?
cionci è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato WoW Forever provato: il MMORPG che la community ...
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita TCL P80 Ultra: con un display AMOLED opaco &egra...
HUAWEI MatePad Air recensione: OLED opaco e tastiera dedicata per lavorare meglio HUAWEI MatePad Air recensione: OLED opaco e tast...
NVIDIA RTX Spark: il PC Windows on ARM costruito per l'IA agentica NVIDIA RTX Spark: il PC Windows on ARM costruito...
Motorola razr fold, dalla conchiglia al formato a libro. La recensione Motorola razr fold, dalla conchiglia al formato ...
Microsoft vuole rispondere al MacBook Ne...
Un processore Intel Haswell del 2013 tor...
AMD FSR 4.1 non conosce confini: arriva ...
AeroSteam Elite 920: il ferro da stiro v...
Steam Deck 2: 6 core e 24 GB di RAM per ...
Microsoft rilancia sulla sovranità...
GeForce RTX 6060: indiscrezioni sulla da...
Quattro agenti Gemini 4 Argon sono morti...
Il supercomputer europeo che sta accorci...
Agenti IA violano oltre 100 siti, coinvo...
Honor Magic V7, prime indiscrezioni sul ...
Amazon vuole 12 reattori nucleari, ma tr...
Antigravity A1, ecco il Remote Controlle...
DRAM e HBM introvabili, il CEO di Dell a...
Giochi Xbox One girano su iPhone in mani...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 21:29.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v