Newsgroup: it.comp.lang.c++
Titolo: delete[]

Ciao a tutti; scusate se continuo a postare domande magari stupide ma
questo periodo mi vengono molti dubbi...
int main() {
	int *p;
	p=new int[100];
	delete[] p;
}
Non ho provato a compilare ma dovrebbe essere corretto.
Sappiamo tutti che non è possibile determinare run-time il numero
degli elementi contenuti in un array dinamico: ma allora come fa
delete[] a sapere quanti elementi deallocare? Non si potrebbe usare lo
stesso meccanismo per sapere il numero di elementi run-time?
Anto

 stesso meccanismo per sapere il numero di elementi run-time?
Se allochi due interi separati con new, avrai un tot di memoria allocata. Se
allochi un array dinamico di due interi, avrai quel tot più un altro piccolo
frammento di memoria allocata. Questo piccolo frammento serve all'operatore
delete[] per conoscere la dimensione dell'array che si andrà a distruggere.
Quindi la dimensione dell'array è in realtà nota all'operatore delete[], ma
non a noi. Non penso vi sia un modo valido per accedere a tali informazioni.
Ciao
Domenico Barra

delete[] a sapere quanti elementi deallocare? 
Lei puo'.
D'altronde e' lo stesso meccanismo alla base della deallocazione
classica con free(). L'allocazione con malloc() comporta che una
piccola porzione di memoria venga riservata per contenere i dati
relativi a quanto e' grande quella porzione.
--
Andrea Laforgia (ICQ 87230455)
------------------------------ 
#exclude <windows.h>

non a noi. Non penso vi sia un modo valido per accedere a tali informazioni.
Avevo pensato ad una cosa simile; però a questo punto, visto che tanto
la memoria viene allocata, mi chiedo perchè non fornire un meccanismo
per trovare la dimensione run-time. Misteri dello standard...

per trovare la dimensione run-time. Misteri dello standard...
Non sarebbe corretto, perche' non portabile.
I puntatori possono essere allocati in qualunque modo, ma esso vincola
la deallocazione. Se alloco con malloc() non posso deallocare con
delete. Se alloco con new non posso deallocare con free().
E mi sto attenendo strettamente allo standard (immagina le versioni
fuori standard per l'allocazione di puntatori, come GlobalAlloc,
VirtualAlloc, ecc.. sotto Windows).
Senza contare versioni "overloaded" di new/delete.
Il nostro operatore unario immaginario "get_dimension_of_pointed_data"
dovrebbe poter agire su qualsiasi puntatore allocato, altrimenti non
servirebbe. Se cosi' non fosse, se ne dovrebbe scrivere una versione
per ogni funzione/operatore di allocazione.
Cosa assolutamente improponibile.


 per trovare la dimensione run-time. Misteri dello standard...
Usa std::vector.
Ciao,
Nicola

per trovare la dimensione run-time. Misteri dello standard...
Ma perché bisogna andarsi a complicare la vita con questi vecchi
metodi da C ? La libreria standard viene incontro proprio a questo
tipo di esigenze, percui non vedo perché non utilizzarla.
Allego un piccolo programmino di esempio, che non ho compilato ma che
bene o male dovrebbe funzionare.
#include<string>
#include<algorithm>
#include<vector>
#include<iostream>
int main()
    {
    std::vector<string>prova;
    prova.push_back("la");
    prova.push_back("nutella");
    prova.push_back("é");
    prova.push_back("buona");
    copy(prova.begin(),prova.end(),ostream_iterator<string,char>
(cout," "));
    int old_size=prova.size();
    cout<<"\n"<<old_size<<"\n";
    vector<string>ariprova;
    ariprova.push_back("ma");
    ariprova.push_back("fa");
    ariprova.push_back("ìngrassare");
    copy(ariprova.begin(),ariprova.end(),back_inserter(prova));
    int new_size=prova.size();
    copy(prova.begin(),prova.end(),ostream_iterator<string,char>
(cout," "));
    cout<<"\n"<<new_size<<"\n";
    cin.get()    //questo é per quelli che si chiedono come mai il
programma si chiude da solo.
    return 0;
    }
Il Ghenio
-----
E'più oscuro del crepuscolo, é più rosso del sangue,
in nome della pace e della giustizia faccio appello a
tutti i poteri più remoti dell'oscurità, perché mi
aiutino a distruggere i miei nemici e tutti coloro
che saranno tanto sciocchi da ostacolarmi. FULMINE ROSSO!!
(Slayers)
-----

Usa std::vector.
Certo, non ci penso su due volte: molto meglio std::vector che gli
array, questo è fuori di dubbio; avevo fatto questa domanda più per
curiosità che per altro (chi meglio di voi riesce a togliermi i dubbi
sul nascere?)
Anto

 Anto
Nella implementazione "standard" dell'operatore "delete" non e' lui che
conosce la quantita' di memoria da deallocare ma bensi' il sistema operativo
chiamato in questione mediante la funzione "free" contenuta nella
implementazione dell'operatore stesso. Se hai i sorgenti delle tue librerie
C++ prova a leggere quelle che riguardano l'operatore in questione.
saluti
Stefano C.

C++ prova a leggere quelle che riguardano l'operatore in questione.
Ma operator delete è un costrutto del linguaggio, non una funzione di
libreria! Quindi non è certo implementato dalla libreria (se dico
qualche idiozia ditemelo); se scrivo questo prog:
int main() {
	int* a = new int;
	delete a;
}
dovrebbe funzionare anche se non linko la libreria standard; dico bene
oppure non ho capito niente su questo punto?
Anto

oppure non ho capito niente su questo punto?
Avete ragione entrambi, nel senso che delete e` un costrutto del
linguaggio (quindi e` sempre presente indipendentemente dalle
librerie utilizzate), ma che diversi compilatori implementano con
chiamate a free. Naturalmente non bisogna assolutamente fare
affidamento a cio`...
Paolo

oppure non ho capito niente su questo punto?
Cosa fanno delete e new non puo' essere deciso che al momento
del link: se infatti ci fosse un modulo che definisce ad esempio...
  void *operator new(size_t size)
  {
    ...
  }
  void operator delete(void *p)
  {
    ...
  }
allora il tuo main e' tenuto a chiamare queste funzioni
invece di quelle standard.
Ovviamente il compilatore non puo' sapere mentre sta
compilando main() se avrai o meno intenzione di fare il
link con un modulo che ridefinisce operator new e/o
operator delete.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

affidamento a cio`...
Ho letto che viene garantito che malloc non si appoggia a
operator new, free non dipende da operator delete ma null'altro.
Personalmente quando ridefinisco operator new e operator delete
mi appoggio a malloc/free (cosa consentita: anzi... credo che
le garanzie fornite dallo standard servano proprio a permettere
una implementazione degli allocatori custom di questo tipo).
Ho anche visto implementazioni della libreria standard che
quando allocano spazio per gli elementi dei container non usano
operator new ma altre funzioni (g++)... non ho capito se questa
e' una cosa ammissibile per lo standard o meno.


 oppure non ho capito niente su questo punto?
Ma qui non si sta parlando di libreria standard, bensi di supporto
runtime del linguaggio, che puo' essere implementato tramite librerie.
 
Ciao,
Nicola

operator new, free non dipende da operator delete ma null'altro.
Questo mi pare ragionevole, se non altro per evitare loop...
Pero` non mi pare una condizione essenziale.
Paolo

 il numero di elementi allocati.
Per standard intendevo come e' implementato normalmente nelle librerie. Io
ho utilizzato compilatori C++ Borland, Metaware, Watcom, per sistemi
embedded e PC, e tutti nella implementazione dell'operatore "delete" alla
fine chiamavano la funzione "free" che si rifaceva al sistema operativo. Non
so se questo sia "standard" vero o solo uno "standard" di fatto.
In questo momento a casa, per diletto, sto utilizzando il gcc con Linux ma
non ho ancora sbirciato i sorgenti delle librerie anche si mi aspetto che si
comporti come le altre.
Ciao
Stefano C.

Stefano Colombo
Ho trovato l'esempio del Metaware:
///////////////////////////////////////////////////////////////////////
// Copyright 1991, 1992 MetaWare Incorporated.  All rights reserved. //
///////////////////////////////////////////////////////////////////////
// delete
extern "C++" void operator delete(void *p) {
    extern "C" void free(void *);
    if (p) free(p);
    }
Ciao
Stefano C.



Ecco anche l'esempio dell'operatore delete[] Metaware:
///////////////////////////////////////////////////////////////////////
// Copyright 1994 MetaWare Incorporated.  All rights reserved. //
///////////////////////////////////////////////////////////////////////
// array delete for C++
extern "C++" void operator delete[](void *p) {
    ::operator delete(p);
    }
ciao
Stefano.
PS: scusate per il messaggio precedente che mi e' scappato due volte.

runtime del linguaggio, che puo' essere implementato tramite librerie.
Forse mi sono spiegato male: solitamente esistono delle opzioni del
linker che mi permettono di generare un eseguibile che non dipenda da
alcuna libreria (utili ad esempio per scrivere il kernel di un O.S.):
se new e delete sono implementati in librerie, come fanno ad essere
usati in un tale programma?
Anto

alcuna libreria
Forse stai parlando di programmi che non devono dipendere da librerie
*shared* o *dinamiche* ... e' tutta un'altra cosa.


 usati in un tale programma?
Basta definirle !
In linux esistono delle funzioni free/malloc ( kfree/kmalloc ); ed il 
kernel le usa spesso; ma sono definite all'interno del kernel stesso 
perche' e' il kernel che si occupa di gestire la memoria. E' cosi' che 
riesce ad evitare di appoggiarsi a librerie.
Il fatto che new/delete siano operatori non vedo xche debbano implicare che 
non vengano definite in librerie esterne. In fondo anche free e malloc sono 
definite in librerie esterne.
E' solo che queste librerie vengono linkate di default ( libc per il C e 
libstdc++ per il C++ sotto linux )

mi appoggio a malloc/free 
E, tra l'altro, su "Inside the C++ Object Model" e' specificato che
new/delete *generalmente* si basano su malloc/free.
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

usati in un tale programma?
Credo che tu stia confondendo un po' di cose...
Qualunque programma, scritto in un qualunque linguaggio, ha
necessariamente bisogno di un "run-time support"; nel caso specifico
il supporto a run-time di un programma scritto in C++ e`
l'implementazione di tutte le funzionalita` previste dal linguaggio,
tanto dei costrutti base (compreso new) che delle funzionalita`
offerte tramite la libreria standard.
Anche l'assembly ha un suo supporto a run time (il firmware e
l'hardware su cui si basa il linguaggio).
Se devi realizzare cose come il kernel di un s.o., hai bisogno di
strumenti che non facciano affidamento su un qualche s.o. o realizzare
le cose in un modo tale da essere tu ad evitare di fare riferimento ad
un qualche s.o. (es. scriverti la tua new)...
Paolo


Credo ti siano state date risposte un po' fuorvianti. Un compilatore
puo' (in pratica avviene quasi sempre) implementare il supporto runtime
tramite librerie. Quello che succede di solito e' che queste librerie
sono fornite in versione dinamica (ovvero DLL) oppure statica (ovvero
LIB).
L'opzione di cui parli di solito effettua il link con le librerie
statiche, dalle quali vengono estratti i moduli oggetto ai quali fa
riferimento il tuo programma e direttamente inseriti nell'eseguibile.
Ciao,
Nicola

un qualche s.o. (es. scriverti la tua new)...
OK, chiaro ed esauriente come al solito.
Ciao Anto