delete[]
-
Original erstellt von Ishildur:
einmal genau darüber nachdenkt, muss dies schon möglich sein, denn wie könnte sonst folgende Anweisung funktionieren ?fast korrekt.
klar macht new[] so nen zaubertrick.
versuch malint* p=new int[10]; cout<<p[-1]<<endl; cout<<p[-2]<<endl; ... delete[] p;
usw.
kann sein, daß dein compiler die größe dort ablegt.
kann aber auch sein, daß er klug ist und für verwaltung nen anderen speicherbereich nimmt. man mag meinen, ne hashtable oder ein trie, die von den daten zu deren verwaltung hüpft, kostet viel, aber naja, die datenlokalität geht hoch, was ja heutzutage oft mehr bringt. dann kannst nur noch mit ganz bösen tricks drankommen.
und natürlich kann er in obigem beispiel aufs speichern der größe ganz verzichten, weil sie ihm beim löschen ja noch bekannt ist.
-
Abgesehen davon, dass es nun wirklich nicht das Problem ist, sich die Grössen selbst allozierter Bereiche zu merken, wenn Du die Standarddatenstrukturen der STL nimmst, die geben meistens Informationen über die Grösse. Sowie sich Dir jenes Problem stellt, stimmt was mit Deinem Layout nicht.
-
int sm[64]; // static memory
cout << sizeof(sm)/sizeof(int); // 64int *dm = new int[64]; // dynamic memory
cout << sizeof(dm)/sizeof(int); // 1Schreibe
int *dm = new int[64]; // dynamic memory cout << sizeof(*dm)/sizeof(int); // 64
Sollte gehen!
-
nö, da kommt 1 raus.
-
Original erstellt von Bitsy:
Abgesehen davon, dass es nun wirklich nicht das Problem ist, sich die Grössen selbst allozierter Bereiche zu merken, wenn Du die Standarddatenstrukturen der STL nimmst, die geben meistens Informationen über die Grösse. Sowie sich Dir jenes Problem stellt, stimmt was mit Deinem Layout nicht.diagnose ist voreilig.
wenn du nicht ein schlechtes gefühl hast, wenn du die redundanz siehst, wie die stl-typen selber speichern und der allokator nochmal speichert, stimmt was mit deiner programmiererei auch net.
-
@Bashar: Stimmt! Ist ja auch logisch, denn der Zeiger bezieht sich ja auf das erste Element im Array
-
wenn du nicht ein schlechtes gefühl hast, wenn du die redundanz siehst, wie die stl-typen selber speichern und der allokator nochmal speichert, stimmt was mit deiner programmiererei auch net.
Gibt es für diesen Satz auch eine allgemein verständliche Übersetzung?
So wie ich den Satz verstehe, ist er quatsch. Und das ist für mich schwer vorstellbar.[ Dieser Beitrag wurde am 01.04.2003 um 15:41 Uhr von HumeSikkins editiert. ]
-
Original erstellt von HumeSikkins:
Gibt es für diesen Satz auch eine allgemein verständliche Übersetzung?irgendwo speichert der new[] die größe eines arrays mit nichttrivialem destruktor ab und manchmal sieht man typen, die zusätzlich zu einem mit new[] angelegten array auch noch dessen größe speichern. das ist doppelte speicherung und sollte einem mißfallen.
es mag quatsch sein, weil in der stl nirgends der new[] verwendet wird.
-
Warum sollte der new-Operator die Größe eines Speicherblocks zusätzlich irgendwo ablegen? Das währe doch blödsinn, weil eine Speicheranforderung an das Betriebsystem geht, und nicht dem new-Operator überlassen wird. Dann könnte das Betriebsystem auch gar nicht den Speicher überwachen. Wenn legt der BS-Speicher Mgr die größe eines Speicherblocks irgendwo ab.
zumal spielt es keine solle ob man nun den new oder new[] Operator verwendet. Beide machen absolut das selbe. Ob ich nun
int* p = new int[10];
mache oder
int* p = operator new(sizeof(int)*10);
spielt keine Rolle. Erstere ist nur einfacher zweitere varainte wird übrigens von der STL verwendet.
-
LOL!
a) das BS gibt Dir nur ganze Seiten von zum Beispiel. 4096 Bytes.
b) delete[] muß so viele destruktoren aufrufen, wie da objekte sind, dazu muss ne zahl gespeichert sein.
c) int* p = new int[10]; und int* p = operator new(sizeof(int)*10); mögen für int gleich sein, aber wer redet davon, daß man nur ints hat?
-
Original erstellt von DragonMaster:
weil eine Speicheranforderung an das Betriebsystem geht, und nicht dem new-Operator überlassen wird.Falsch. Das mag bei einzelnen Implementationen so sein, schließlich macht der Standard keine Aussage darüber. Aber bei den Betriebssystemen die ich kenne würde das nicht funktionieren (DOS, Unix). Die Runtime benutzt natürlich die OS-Funktionen, um mehr Speicher zu bekommen. Aber in einer anderen Granularität als du new anwendest. Das ist wie mit dem std::vector ... ein einzelnes push_back führt idR nicht zur Neuallokation, das passiert erst, wenn eine bestimmte Schwelle überschritten wird.
-
@Volkard
Ok. Hatte deinen Satz falsch verstanden. Dachte du meintest der Allokator würde zusätzlich zum Container noch die Größe speichern.Auf der anderen Seite finde ich deinen Einwand etwas merkwürdig. Schließlich gibt es keine portable Möglichkeit an die durch den op new erzeugte Information zu kommen.
Das ist zwar schade, aber solange es die Realität ist, sehe ich irgendwie nicht wie man um das Speichern der Größe drum rum kommt.
-
Original erstellt von HumeSikkins:
Auf der anderen Seite finde ich deinen Einwand etwas merkwürdig. Schließlich gibt es keine portable Möglichkeit an die durch den op new erzeugte Information zu kommen.
Das ist zwar schade, aber solange es die Realität ist, sehe ich irgendwie nicht wie man um das Speichern der Größe drum rum kommt.Ja, es ist schade. Man hat ein ungutes Gefühl dabei, daß man nicht ran darf. Es wäre doch so fein, wenn man dürfte. usw.
Und natürlich ist es legitim, zu fragen: "wie kommt man denn da ran?".
Wir wissen ja, daß es keinen portablen Weg gibt.
Aber da schrieb einer "Sowie sich Dir jenes Problem stellt, stimmt was mit Deinem Layout nicht."
Und das hielt ich für ein wenig gar oberdreist. Also schrieb ich ihm, daß er nen knall hat, wenn er nichtmal das legitime anliegen sieht.ich wünschte mir auch machmal, daß es einen legitimen weg gäbe.
-
wenn man die groesse will ist eine
template <class Type>
class YAarray{
private:
T *varray;
int size;
public:
// konstruct init access destuct hier//
};mit weniger aufwand zu haben
wenn man das globale ueberwachungs Konzept nutzen wuerde muesste man ja suchen und da is die eine variable mehr nich schlimm.
-
Das Problem warums nicht geht (hat mir mal einer von Euch hier erklärt) ist doch, dass es sein kann, dass new z.B. einen größeren Block belegt, als man anfordert, weils schneller sein kann immer 32-Bit-Blöcke o.ä. zu reservieren.
Und das ist natürlich System- und Implementierungsabhängig.Der Wert, der für das delete[] also irgendwo gespeichert wird ist also >= dem angeforderten und würde einem in den meisten Fällen nicht weiterhelfen. Der angeforderte wird hingegen nirgens gespeichert, weswegen man ihn extra speichern muss -> das ist keine redundante Datenhaltung
Hat man allerdings ein dynamisch wachsendes Array, wärs aber vielleicht gerade nützlich den tatsächlich reservieren Speicher zu kennen.
-
und wieso wird dann immer die richtige Zahl von destruktoraufrufen aufgerufen?
-
hm, das ist ne gute Frage, wegen welcher ich Euch bitten muss meinen obigen Beitrag als nie geschrieben zu betrachen :o
-
klaro
-
Original erstellt von <hhh>:
und wieso wird dann immer die richtige Zahl von destruktoraufrufen aufgerufen?aber bei buildins und PODs könnte man trozdem den schnelleren block allocier modus benutzen
alles unter einen hut bringen könnte man das so
foo * f = new foo[20]; pod * p = new(block_alloc) pod[100]; size_of_alloc( f ); // 20 size_of_alloc( p ); // in der docu zu size_of_alloc würde dann stehen // das wenn man den block mit den block_alloc new geholt hat // das ergebnis (die zahl, nicht der aufruf) undefiniert ist
-
Original erstellt von Dimah:
**aber bei buildins und PODs könnte man trozdem den schnelleren block allocier modus benutzen
**hab ich auch nie was gegen gesagt