Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Usare new e malloc() nello stesso programma
Forum - C/C++ - Usare new e malloc() nello stesso programma

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 7:29
Venerdì, 16/01/2015
Buongiorno.

Sfogliando il codice della classe Buffer (vedi sotto) ho visto che nell'implementazione vengono chiamate le funzioni del C malloc() e free(). Ricordo che tempo fa lessi un manuale nel quale si avvertiva che era da evitare l'uso delle funzioni di gestione della memoria dinamica del C in programmi nei quali viene usato l'operatore C++ new (direi che l'uso di new è pressoché inevitabile in qualsiasi programma in C++). In quel manuale si adombrava la possibilità che, facendolo, la luna uscisse dall'orbita, cadessero i denti a tutti i gatti del quartiere, il programmatore venisse cornificato dalla moglie e così via.

Qualcuno mi chiarisce le idee? Si possono tranquillamente usare i due modelli di gestione della memoria dinamica nello stesso programma oppure no?

http://www.pierotofy.it/pages/sorgenti/dettagli/19356-Buff ...

Ultima modifica effettuata da AldoBaldo il 16/01/2015 alle 7:30


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 10:01
Venerdì, 16/01/2015
No, non è affatto consigliabile.

1) malloc alloca nell'heap, la new non è detto che lo faccia nell'heap

2) new è un operatore di cui puoi scrivere l'override senza problemi, non è così per la malloc

3) la new provvede a chiamare anche il costruttore dell'eventuale classe (la delete il distruttore)

4) la new è tipizzata, la malloc restituisce void *

In quel codice di cui hai inserito il link, NON va bene l'uso di malloc/free; dovrebbe essere utilizzata la new/delete (a parte il fatto che ci sarebbero tante cose da dire su quell'implementazione in diverse parti del codice ...)




Ultima modifica effettuata da nessuno il 16/01/2015 alle 10:04


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 10:05
Venerdì, 16/01/2015
Ti dico la verità: non è bellissimo, ma spesso mischio malloc e new, infatti adesso devo sistemare tutti i 20.000 malloc sparsi per tutto il programma.......

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 10:09
Venerdì, 16/01/2015
Testo quotato

Postato originariamente da TheDarkJuster:
spesso mischio malloc e new



Pessima idea ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 10:59
Venerdì, 16/01/2015
Ma non per allocare oggetti, così devo correggere solo la metà delle allocazioni.....

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 13:08
Venerdì, 16/01/2015
Da notare anche che (cosa non da sottovalutare) una new che fallisce lancia una eccezione (da gestire), mentre la malloc può "silenziosamente" restituire un NULL che il codice (e ne ho visto di codice simile) non controlla ... con le conseguenze del caso.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 18:21
Venerdì, 16/01/2015
Grazie per le risposte, però sono un po' tonto e ci sono cose che ancora mi sfuggono. Nessuno e Dark, se avete pazienza...

Conoscevo già la differenza tra malloc() e "new" per quanto riguarda il chiamare o non chiamare il costruttore. Simmetricamente, sapevo già che free() non chiama il distruttore e "delete" sì. Sapevo anche che "new" può essere "personalizzato" e malloc() no, così come sapevo che "new" è tipizzata e malloc() dà sempre void*. A suo tempo ci ho messo un po' prima di capire che quando "new" fallisce non restituisce necessariamente NULL come fa malloc() e che comunque lancia un'eccezione che deve essere gestita, però ora lo do per scontato e so come cavarmela discretamente con "try" e "catch". Fin qui tutto bene.

Però sono ancora confuso da due cose:

1. Che significa dire che malloc alloca nell'heap, mentre "new" non è detto che lo faccia nell'heap? Cioè, credo di sapere con abbastanza cognizione di causa cosa sono l'heap e lo stack (ho scritto "abbastanza" non a caso...), però non ho ben capito in quale altro luogo potrebbe allocare "new".

2. Dato per scontato che nel dubbio ho sempre evitato di mischiare "new" e malloc(), nel manuale del quale parlavo nel commento precedente si alludeva a misteriose "interazioni" nefaste tra un sistema e l'altro, "interazioni" che avrebbero potuto (testuali parole, le ricordo) "distruggere il sistema di allocazione dinamica della memoria". Un'espressione ben curiosa che non veniva spiegata meglio di così e che non ho mai capito.

Mi adeguo senz'altro alle indicazioni di chi ne capisce più di me (se l'autore ha scritto e pubblicato un manuale cartaceo per McGrawHill vorrà dire qualcosa) ma, siccome mi piace poco accettare le cose in modo fideistico, sarei più soddisfatto se potessi sapere e magari capire almeno un po' cosa c'è dietro. Ah, il manuale credo sia dei tardi anni '90.

Ultima modifica effettuata da AldoBaldo il 16/01/2015 alle 18:22


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 21:13
Venerdì, 16/01/2015
Guarda le cose sono semplici e coerenti.

Nessuno ti assicura che l'implementazione della new/delete siano legate alla malloc/free (sia perché tu potresti non sapere con certezza come operano i due operatori nella libreria del compilatore che usi e sia perché altre librerie di terze parti potrebbero ridefinire gli operatori).

Per questo semplice motivo

1) la new potrebbe allocare spazio su disco, su chiave USB, su memoria SSD, su un dispositivo hardware esterno dedicato e implementare un meccanismo di scambio dati con un'area di memoria nell'heap (ovviamente la delete si comporterebbe di conseguenza);

2) la new potrebbe anche effettuare particolari inizializzazioni, software e hardware, di cui non si ha conoscenza (magari nel sottosistema di gestione della memoria);

3) dato il punto 1), se usassi la malloc per allocare memoria e poi la delete per liberarla, ovviamente la delete si comporterebbe "pensando" che la new abbia fatto tutto quello che serviva e sarebbe un bel guaio (ovviamente anche il contrario sarebbe un problema)

4) dato il punto 2), se usassi la free, il sistema non ritornerebbe nello stato corretto e, in una situazione di gestione particolare della memoria, la free non "pulirebbe" correttamente le tabelle facendo "saltare" tutto il sistema di gestione della memoria.

In pratica, la regola è semplice

malloc/free

new/delete

new []/delete []

magari anche mischiate nello stesso codice sorgente, ma coerenti.

P.S. Dove ho scritto "potrebbe" significa, ovviamente, che non è escluso che con un compilatore non esistano problemi nel fare malloc/delete o new/free perché la libreria specifica lavora comunque correttamente. MA bisogna pensare al caso "generale" e quindi "evitare" pratiche che oggi, in un sistema e con un compilatore, funzionano, domani, altro sistema e/o compilatore, non vanno più

Ultima modifica effettuata da nessuno il 16/01/2015 alle 21:16


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:12
Venerdì, 16/01/2015
Ah! Be', sì, messa così ha senso e riesco a capirla (credo). Vediamo se è vero.

1. Il problema si pone particolarmente (ma non solo) se "new" è stato in qualche modo personalizzato/ridefinito, perché a "new" potresti far fare praticamente qualsiasi cosa, come a qualsiasi altro operatore. Giusto?

2. Il problema nasce se usi free() per liberare "roba" allocata (in effetti, "creata") con "new", e/o "delete" per liberare roba allocata con malloc(), perché visto quel che si è detto nel punto precedente finisci per non sapere realmente cosa stai liberando. Giusto?

Dunque nel manuale non si intendeva dire che non puoi usare malloc()/free() e "new"/"delete" nello stesso programma, ma che non si può usare malloc()/"delete" e "new"/free(), il che avrebbe perfettamente senso anche per me che non sono certo un esperto. Se le cose stanno così, ovvero se ho capito bene, il manuale non era per niente chiaro e lasciava un po' troppe cose nel mondo dei sottintesi. Per fortuna c'è Pierotofy.it! :)

Nessuno, mi dici ancora solo se ho capito bene o no? In caso venisse fuori che non ho ancora capito, vedrò di pensarci ancora un po' su.


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo