Fragen zu new und delete und weiteres
-
Hi.
Ich hätte ein paar Fragen zu den new und delete Operatoren.1.) Kann man prüfen ob ein Pointer auf eine per new auf dem Heap erzeugte Speicherstelle zeigt? Es kann nämlich unter Umständen vorkommen dass in meinem Code schon delete aufgrufen wird bevor new aufgerufen wurde (Habe delete im Deconstructor, angelegt wird der Speicher von einer Funktion die extra aufgerufen werden muss und ja, die Werte müssen langlebig sein). Oder wird eventuell sogar eine Exception geworfen?
2.) Folgender Code angenommen:
int* i; i = new int[10]; i = new int[15];Wird hierbei:
a.) Neuer Heapspeicher erstellt und die ersten 10 Ints liegen als Speicherleichen herum?
b.) Die ersten 10 Ints zunächst freigegeben (was mich stark wundern würde)
c.) Schlägt die Funktion fehl?
(Leider keinen Compiler hier, kanns nicht testen...)3.) Anderes Gebiet: Wie groß ist der Stackspeicher moderner Prozessoren? Was kann man ihnen an lokalen Variablen zumuten?
4.) std::vector als "bester" Buffer? Wozu noch die Gefahr von Overflows eingehen wenn man sich einfach seinen "std::vector<char> buffer" erstellen kann, mit reserve für neue Elemente Platz schaffen kann. Man kann den Vector ja auch wie ein normalen C-String benutzen ("buffer[]") oder liege ich da falsch ?
Und wie performant ist die ganze Geschichte?Wäre nett wenn mir jemand antworten könnte

Grüße
-
Icematix schrieb:
1.) Kann man prüfen ob ein Pointer auf eine per new auf dem Heap erzeugte Speicherstelle zeigt?
Eigentlich nicht.
a.) Neuer Heapspeicher erstellt und die ersten 10 Ints liegen als Speicherleichen herum?
Ja.
3.) Anderes Gebiet: Wie groß ist der Stackspeicher moderner Prozessoren? Was kann man ihnen an lokalen Variablen zumuten?
1M ist üblich.
4.) std::vector als "bester" Buffer?
Nein und Ja. Wenn Du noch im totalen Ratestadium bist, ist vector sicherlich besser.
Wozu noch die Gefahr von Overflows eingehen wenn man sich einfach seinen "std::vector<char> buffer" erstellen kann, mit reserve für neue Elemente Platz schaffen kann. Man kann den Vector ja auch wie ein normalen C-String benutzen ("buffer[]") oder liege ich da falsch ?
Wer ungeschickt genug ist, kann immer overflows bauen.
Und wie performant ist die ganze Geschichte?
vector ist schnell.
-
Icematix schrieb:
Wozu noch die Gefahr von Overflows eingehen wenn man sich einfach seinen "std::vector<char> buffer" erstellen kann, mit reserve für neue Elemente Platz schaffen kann. Man kann den Vector ja auch wie ein normalen C-String benutzen ("buffer[]") oder liege ich da falsch ?
Und wie performant ist die ganze Geschichte?Im Grunde ist std::vector<> nicht viel mehr als ein dynamisches Array nebst der nötigen Buchhaltung, die man sonst händisch mitführen müsste. Bei der richtigen Optimierung, wenn die ganzen Indirektionen der Funktionsaufrufe wegoptimiert werden, sollte sich die Performance nicht von einem handcodierten dynamischen Array unterscheiden.
-
Icematix schrieb:
1.) Kann man prüfen ob ein Pointer auf eine per new auf dem Heap erzeugte Speicherstelle zeigt?
Nein, und Code, der dies erforderlich macht, weist oft auf einen Designfehler hin.
Icematix schrieb:
Es kann nämlich unter Umständen vorkommen dass in meinem Code schon delete aufgrufen wird bevor new aufgerufen wurde (Habe delete im Deconstructor, angelegt wird der Speicher von einer Funktion die extra aufgerufen werden muss und ja, die Werte müssen langlebig sein).
Dann setze doch Nullzeiger ein.
deleteauf Nullzeiger macht nichts. Übrigens heisst es Destruktor.
-
Habe delete im Deconstructor, angelegt wird der Speicher von einer Funktion die extra aufgerufen werden muss und ja, die Werte müssen langlebig sein
Du kannst jederzeit delete auf einen 0-Pointer machen. Da passiert dann einfach nix. Wenn du also einen Pointer im konstruktor nicht initialisierst (bzw du solltest ihn explizit mit 0 initialisieren!), dann im Dekonstruktor delete aufrufst is das vollkommen legitim.
-
Nachtrag:
Wollte noch schreiben, das es so im Standard festgelegt worden ist.
-
Und solltest du doch noch irgendwo an einer anderen Stelle ein delete nutzen, vergiss nicht, danach den Zeiger wieder auf 0 zu setzen. Denn ein doppeltes delete ist nicht so geil (Verhalten undefiniert AFAIK, sowas vermeidet man)