Muss char * = „string“ oder char * = new char[6] zerstört werden?
Frage
Ich nehme das an char* = "string"
ist das Gleiche char* = new char[6]
.Ich glaube, diese Zeichenfolgen werden auf dem Heap und nicht auf dem Stapel erstellt.Muss ich sie also zerstören oder ihren Speicher freigeben, wenn ich sie nicht mehr verwende, oder werden sie von selbst zerstört?
Lösung
NEIN.Sie müssen Zeichenfolgen nur dann manuell freigeben, wenn Sie den Speicher mithilfe von manuell selbst zuweisen malloc
Funktion (in C) oder die new
Operator (in C++).Wenn Sie es nicht verwenden malloc
oder new
, dann ist die char*
oder eine Zeichenfolge wird auf dem Stapel oder als Konstante zur Kompilierungszeit erstellt.
Andere Tipps
NEIN.Wenn du sagst:
const char* c = "Hello World!";
Sie weisen c einer „bereits vorhandenen“ Zeichenfolgenkonstante zu, die NICHT dasselbe ist wie:
char* c = new char[6];
Nur im letzteren Fall weisen Sie Speicher auf dem Heap zu.Rufen Sie also delete auf, wenn Sie fertig sind.
Ich gehe davon aus, wenn ich es tue
char* = "string"
Es ist das Gleiche wiechar* = new char[6]
.
NEIN.Der erste Schritt besteht darin, eine Konstante zu erstellen.Es zu ändern ist undefiniertes Verhalten.Aber um Ihre Frage zu beantworten;Nein, du musst sie nicht zerstören.Und nur eine Anmerkung, immer verwenden std::string
wenn möglich.
Der Name des Spiels lautet: „Zerstöre nur das, was du geschaffen hast“.Hier sind die Paare:
malloc
/free
calloc
/free
new
/delete
new []
/delete []
Da Sie die 2. Zeichenfolge mit erstellt haben new []
, die Verantwortung liegt bei Ihnen, es zu zerstören delete []
.Anruf delete [] string2
wenn du fertig bist.
Wenn Ihr Code nun kompliziert genug ist und es schwierig macht, den Überblick über Löschungen zu behalten, sollten Sie die Verwendung von bereichsbezogenen Zeigern oder automatischen Zeigern in Betracht ziehen.Der boost::scoped_ptr
Die Klasse aus der Boost-Bibliothek ist ein guter Anfang.Schauen Sie auch in die RAII Redewendung, ziemlich praktisches und nützliches Zeug.
Sie sind nicht gleich.Ihr erstes Beispiel ist eine konstante Zeichenfolge, daher wird sie definitiv nicht vom Heap zugewiesen.Ihr zweites Beispiel ist eine Laufzeitspeicherzuweisung von 6 Zeichen, die aus dem Heap stammt.Sie möchten Ihr erstes Beispiel nicht löschen, müssen es aber tun delete []
Dein zweites Beispiel.
Sie wissen nicht, wo die Zeichenfolgenliterale gespeichert sind.Möglicherweise handelt es sich sogar um einen Nur-Lese-Speicher, daher sollte Ihr Code wie folgt lauten:
const char* c = "string";
Und ein neu char-Array sollte sein löschend wie jeder andere dynamisch zugewiesene Speicherbereich.
new ist immer eine Zuweisung, während die Inline-Definition einer Zeichenfolge die Daten tatsächlich in das Programm selbst einbettet und nicht geändert werden kann (einige Compiler ermöglichen dies durch einen cleveren Trick, machen Sie sich nicht die Mühe).
Einige Compiler geben Inline-Strings ein, sodass Sie den Puffer nicht ändern können.
char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
Mal sehen, was GCC 4.8 x86-64 Linux macht
Programm:
#include <cstdio>
int main() {
const char *s = "abc";
char *sn = new char[4];
sn[3] = '\0';
std::printf("%s\n", s);
std::printf("%s\n", sn);
}
Kompilieren und dekompilieren:
g++ -ggdb -std=c++98 a.cpp
objdump -CSr a.o
Die Ausgabe enthält:
const char *s = "abc";
8: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
f: 00
c: R_X86_64_32S .rodata
char *sn = new char[4];
10: bf 04 00 00 00 mov $0x4,%edi
15: e8 00 00 00 00 callq 1a <main+0x1a>
16: R_X86_64_PC32 operator new[](unsigned long)-0x4
1a: 48 89 45 f8 mov %rax,-0x8(%rbp)
Deutung:
char *s = "abc"
gehört in.rodata
.Also kannst du nichtfree
es in irgendeiner Weise.char *sn = new char[4];
kommt aus der Ausgabe vonoperator new[]
.Sie sollten es also freigeben, wenn Sie können.