Torna indietro   Hardware Upgrade Forum > Software > Programmazione

PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu
PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu
Il modello "build to order" di PCSpecialist permette di selezionare una struttura base per un sistema, personalizzandolo in base alle specifiche esigenze con una notevole flessibilità di scelta tra i componenti. Il modello Lafité 14 AI AMD è un classico notebook clamshell compatto e potente, capace di assicurare una elevata autonomia di funzionamento anche lontano dalla presa di corrente
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto
Nothing con il suo nuovo Phone 4(a) conferma la sua identità visiva puntando su una costruzione che nobilita il policarbonato. La trasparenza resta l'elemento cardine, arricchita da una simmetria interna curata nei minimi dettagli. Il sistema Glyph si evolve, riducendosi nelle dimensioni ma aumentando l'utilità quotidiana grazie a nuove funzioni software integrate e notifiche visive. Ecco tutti i dettagli nella recensione completa
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale
Nelle ultime settimane abbiamo provato la Corsair Vanguard Air 99 Wireless, una tastiera tecnicamente da gaming, ma che in realtà offre un ampio ventaglio di possibilità anche al di fuori delle sessioni di gioco. Flessibilità e funzionalità sono le parole d'ordine di una periferica che si rivolge a chi cerca un prodotto capace di adattarsi a ogni esigenza e ogni piattaforma
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-02-2010, 20: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 20:41.
abestos è offline   Rispondi citando il messaggio o parte di esso
Old 08-02-2010, 20: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, 11: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, 11: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, 16: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, 17: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, 18: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, 18: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, 19: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, 08: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, 14: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, 17: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, 19: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, 20: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, 23: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, 09: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, 11: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, 11: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, 16: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, 16: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


PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu PC Specialist Lafité 14 AI AMD: assemblat...
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto Recensione Nothing Phone 4(a): sempre iconico ma...
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale Corsair Vanguard Air 99 Wireless: non si era mai...
Ecovacs DEEBOT T90 PRO OMNI: ora il rullo di lavaggio è ampio Ecovacs DEEBOT T90 PRO OMNI: ora il rullo di lav...
Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo Recensione Samsung Galaxy S26 Ultra: finalmente ...
Riceve il reso di una RTX 5090 da 4.000 ...
Gli utenti con GPU Intel non possono gio...
Un agente AI visita 5.000 siti dove un u...
IA, virtualizzazione e cyber resilienza:...
AMD aggiorna FSR alla versione 4.1. Migl...
Nuovi suffissi internet 2026: per la sec...
Claudy Day: tre vulnerabilità in ...
Record di efficienza per i pannelli sola...
SteamOS 3.8 è disponibile in ante...
Opel in Formula E dalla Stagione 13: con...
Windows 11 26H1: ecco le scadenze esatte...
Arriva HiSecEngine USG6000G, la nuova ga...
Xiaomi SU7 2026 ufficiale con 902 km di ...
Il tuo vecchio iPhone potrebbe essere gi...
Già disponibile un primo aggiorna...
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: 19:54.


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