Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Nuova Dacia Spring, del modello precedente resta solo il nome: più grande, più efficiente e ora prodotta in Europa
Nuova Dacia Spring, del modello precedente resta solo il nome: più grande, più efficiente e ora prodotta in Europa
La seconda generazione della citycar elettrica di Dacia passa alla piattaforma RGEV small di Renault Group, cresce di 15 cm in lunghezza e 18 cm in larghezza, adotta un motore da 80 CV e una batteria LFP da 27,5 kWh per 250 km WLTP. Prezzi da 17.900 euro, produzione a Novo Mesto in Slovenia.
BOOX Picco: l'ebook reader minuscolo è una genialata, e si può attaccare allo smartphone
BOOX Picco: l'ebook reader minuscolo è una genialata, e si può attaccare allo smartphone
BOOX ha portato sul mercato Picco, un e-reader da 3,97 pollici che pesa 58 grammi e si aggancia al retro dello smartphone con un anello magnetico. Lo abbiamo usato con Pixel 11 Pro XL e iPhone 18 Pro per capire se un formato così ridotto regga la prova della lettura quotidiana
AMD EPYC Venice: dentro Zen 6, i SoC a 256 core e la sfida al costo della memoria
AMD EPYC Venice: dentro Zen 6, i SoC a 256 core e la sfida al costo della memoria
A Las Vegas AMD ha svelato i dettagli architetturali delle CPU EPYC di sesta generazione, note con il nome in codice Venice. Nuovi core Zen 6 e Zen 6c costruiti a 2 nanometri, fino a 256 core per socket, 16 canali di memoria, interfaccia PCI Express 6.0 e un'intera famiglia di proposte che va da Venice SP7 a Verano. Senza dimenticare la memoria, oggi la voce di costo più pesante in un server: AMD risponde con CXL 3.1 e con la tecnologia software MEXT, che porta la memoria flash dentro la gerarchia della DRAM.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 06-06-2008, 18:54   #1
Albi89
Senior Member
 
Iscritto dal: May 2004
Città: Napoli
Messaggi: 773
[C++] Memory leaks for dummies

Ciao a tutti!
In vista di un esame ho deciso di "condividere" con voi tutti un paio di piccoli dubbi che mi attanagliano:

Il primo riguarda i metodo set e get.
Mettiamo il caso di una classe Persona che registri il nome di una persona, sotto forma di array char allocato dinamicamente.
Non mi sembra conveniente far ritornare dal metodo get_nome() il puntatore, perchè poi potrei utilizzarlo per modificare arbitrariamente un membro private.
Com'è corretto comportarsi?
Pensavo di creare un char* temporaneo "temp" e di allocare una nuova stringa, ritornado questa.
Il problema è che talvolta il metodo get_nome() potrebbe essere usato solo per stampare sul cout: in questo caso avrei allocato spazio che non potrei più recuperare...

Il secondo riguarda la realizzazione in C++ della "inclusione lasca", ossia a mezzo di puntatore.

Sia Persona una classe che definisce nome e età di una persona e Automobile una classe che contiene (in maniera lasca) una Persona.
Realizzo un codice simile:
Codice:
Persona* pippo = new Persona("Pippo", 23);
Automobile pippomachine("Opel Corsa", pippo);
All'interno del costruttore di Automobile, che contiene un membro Persona* guidatore, specifico:
Codice:
this->guidatore = pippo;
E' importante però che il nostro pippo "sopravviva" alla distruzione della macchina: dunque il distruttore di Automobile deve ignorare semplicemente il suo guidatore.

In molti casi, nei compiti era richiesta la creazione di nuovi oggetti sulla base di oggetti preesistenti.
In questo caso, per mantenere la relazione di "inclusione lasca", devo allocare un nuovo oggetto Persona copia di quello originale, o eseguire una "copia superficiale" del solo puntatore?

Se creo un nuovo oggetto Persona, in questo caso il distruttore dovrebbe prendersi anche la responsabilità di deallocarlo: dovrei allora aggiungere qualcosa di molto poco carino come una variabile booleana che mi informa se l'oggetto contenuto è stato allocato in fase di copia o meno, in modo da inserire un controllo nel distruttore per eventualmente deallocarlo... ma mi sembrava abbastanza brutto

Concettualmente non ho insomma ancora capito se, in caso di contenimento lasco (quindi a mezzo puntatore) è corretto copiare IL SOLO puntatore (quindi se modifico il "guidatore" della prima automobile modifico anche quello della seconda perchè sono sostanzialmente lo stesso) oppure se va realizzato ALLOCANDO un nuovo oggetto.

Grazie a tutti per i consigli
__________________
If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
--Gerald Weinberg
Albi89 è offline   Rispondi citando il messaggio o parte di esso
Old 06-06-2008, 19:30   #2
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
per il primo problema basta ritornare un puntatore const:
Codice:
const char *get_name();

edit - anzi, oserei addirittura dire:
Codice:
const char *get_name() const;
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 06-06-2008, 19:38   #3
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2795
Forse questo può esserti utile:
LINK
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 06-06-2008, 19:50   #4
Albi89
Senior Member
 
Iscritto dal: May 2004
Città: Napoli
Messaggi: 773
Quote:
Originariamente inviato da 71104 Guarda i messaggi
per il primo problema basta ritornare un puntatore const:
Codice:
const char *get_name();

edit - anzi, oserei addirittura dire:
Codice:
const char *get_name() const;
Quindi non è reato ritornare un puntatore, basta che non sia possibile modificare il dato?
A volte qualche assistente del prof mi ha fatto una capa tanta che è opportuno ritornare sempre una copia dell'elemento per non violare l'information hiding... effettivamente anche a me sembrava un po' pesante come storia
__________________
If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
--Gerald Weinberg
Albi89 è offline   Rispondi citando il messaggio o parte di esso
Old 06-06-2008, 20:40   #5
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
l'unico che ha il diritto di dire se è reato o meno è il compilatore, o al limite lo standard nei casi in cui i due si contraddicono; i professori spesso non hanno voce in capitolo.
prova ad implementare il prototipo che ti ho scritto e dimmi se ottieni errori di compilazione (frase retorica: io ho scritto mille volte cose del genere, mai il minimo problema).
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 12:52   #6
arara
Senior Member
 
L'Avatar di arara
 
Iscritto dal: Aug 2007
Messaggi: 1270
Se ritorni un puntatore const il valore della stringa puo essere comunque modificato con un const_cast.
Io preferisco ritornare una copia per valore, un puntatore const lo prendo in considerazione solo se effettivamente si verifica un collo di bottiglia.
arara è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 13:54   #7
Albi89
Senior Member
 
Iscritto dal: May 2004
Città: Napoli
Messaggi: 773
Sì ma se ho una stringa realizzata come char* e allocata dinamicamente come posso fare a copiarla senza "perdere" la memoria che alloco?
__________________
If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
--Gerald Weinberg
Albi89 è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 13:55   #8
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
Quote:
Originariamente inviato da arara Guarda i messaggi
Se ritorni un puntatore const il valore della stringa puo essere comunque modificato con un const_cast.
questa è la porcata, non il ritornare un puntatore interno
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 15:41   #9
arara
Senior Member
 
L'Avatar di arara
 
Iscritto dal: Aug 2007
Messaggi: 1270
Quote:
Originariamente inviato da Albi89 Guarda i messaggi
Sì ma se ho una stringa realizzata come char* e allocata dinamicamente come posso fare a copiarla senza "perdere" la memoria che alloco?
In questo caso deve deallocare la memoria quello che ha chiamato get_name, e non è una bella soluzione.
Anche ritornando un puntatore const devi stare attento però: se l'oggetto che contiene l'array dinamico viene cancellato allora il puntatore che a cui è stato assegnato il valore di ritorno di get_name non contiene piu un indirizzo valido, e se viene usato da qualche altra parte rischi di avere qualche serio problema.
La cosa piu semplice è creare una classe che gestisce la stringa e ritornarla per valore invece di usare direttamente un array dinamico.

Ultima modifica di arara : 07-06-2008 alle 15:43.
arara è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 16:47   #10
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2795
Veramente nel link che avevo postato c'era la soluzione al problema, anche se la trovo un po' scomoda da realizzare
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 07-06-2008, 20:53   #11
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
se proprio si vuole evitare di ritornare il puntatore const (soluzione più che decente secondo me) come soluzione ci sarebbe quest'altra (scrivo dichiarazione ed implementazione delle classi in un unico sorgente per fare prima):
Codice:
class CName
{
private:
	char *Content;

public:
	CName(const char *Data)
	{
		size_t Size = strlen(Data) + 1;
		Content = new char[Size];
		memcpy(Content, Data, Size);
	}

	~CName()
	{
		delete Content;
	}

	operator const char* ()
	{
		return Content;
	}
};

class CNamed
{
private:
	char *Name;

public:
	CName GetName()
	{
		return Name;
	}

};

.
.
.

CNamed NamedObject;

.
.
.

cout << NamedObject.GetName();  // nessun leak
credo si possa tranquillamente fare anche utilizzando std::string, senza creare una nuova classe CName.
71104 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Nuova Dacia Spring, del modello precedente resta solo il nome: più grande, più efficiente e ora prodotta in Europa Nuova Dacia Spring, del modello precedente resta...
BOOX Picco: l'ebook reader minuscolo è una genialata, e si può attaccare allo smartphone BOOX Picco: l'ebook reader minuscolo è un...
AMD EPYC Venice: dentro Zen 6, i SoC a 256 core e la sfida al costo della memoria AMD EPYC Venice: dentro Zen 6, i SoC a 256 core ...
HONOR Pad X9 Max recensione, schermo ultra large a meno di 400 euro HONOR Pad X9 Max recensione, schermo ultra large...
Lenovo ThinkPad X1 Carbon Gen 14: il business ultraleggero si rinnova dall’interno Lenovo ThinkPad X1 Carbon Gen 14: il business ul...
L'accordo tra Google e il Napoli continu...
Remus Stealer: così il malware rivendica...
Internet a casa senza fibra né linea tel...
Roborock Saros 20 Flow Complete a 799€ s...
Insta360 X5 a 439€ su Amazon: la videoca...
GWM sfida la Ferrari SF90: la prima supe...
Jensen Huang deve tornare: oltre 1.600 d...
Le cuffie Xiaomi Redmi Neo a soli 39,99€...
Il DLSS ha un rivale? Apex Neural Render...
TV Samsung da 75 pollici a soli 499€ (in...
Cybertruck non muore (quasi): Tesla post...
Wolfenstein 3 è ufficiale: Machin...
Leapmotor Lafa 5 si aggiorna con 800 vol...
Gemini 4 Hydrogen, più veloce di ...
Torna il portatile HP con GeForce RTX 50...
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: 11:14.


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