Wieso gibt "das" keinen Memoryleak?
-
theliquidwave schrieb:
Also ist es genau das gleiche Verhalten wie mit
char *pszBla;?Was genau meinst Du? Ein Zeiger ist kein Array und ein Array ist kein Zeiger. Das ist ein wichtiger Unterschied.
theliquidwave schrieb:
Dort bleibt das Literal ja auch für immer bestehen, aber ich kann es halt kopieren, stimmts?
String-Literale haben immer eine statische Lebensdauer (existieren schon bevor die main läuft oder andere dynamische Initialisierer und bleiben solange da, bis das Programm beendet worden ist) und stehen irgendwo im Speicher. Das ist unabhängig davon, was Du mit dem Literal anstellst.
theliquidwave schrieb:
Was passiert eigentlich, wenn man auf ein Literal ein
delete[]anwendet?Was da genau passieren soll steht nirgens definiert. Das fällt unter "Undefiniertes Verhalten". Unter Linux schmiert dann das Programm ab, wenn ich mich richtig erinnere. Kannst Du ja mal ausprobieren. Aber wie gesagt, kannst Du Dich auf keine bestimmtes Verhalten verlassen.
-
theliquidwave schrieb:
pszBla ist nun gelöscht (der char*), aber das Literal existiert noch, richtig?
Das worauf pszBla zeigt ist gelöscht (also der new char[32]). pszBla existiert so lange bis der aktuelle Scope verlassen wird. Das Literal ist von keiner dieser Aktionen betroffen:
a) Es wurde kopiert, hat also selber nichts mehr mit dem was darauf folgt zu tun.
b) Es ist ein Literal und steht fest und unveränderlich im Programm.edit: Unter Linux passiert übrigens dies, wenn man ein Literal freigeben will:
*** glibc detected *** ./a.out: free(): invalid pointer: 0x0000000000400edc *** ======= Backtrace: ========= /lib/libc.so.6[0x2b22cda04dd6] /lib/libc.so.6(cfree+0x6c)[0x2b22cda0974c] ./a.out[0x400b3f] /lib/libc.so.6(__libc_start_main+0xfd)[0x2b22cd9adabd] ./a.out[0x400919] ======= Memory map: ======== 00400000-00402000 r-xp 00000000 09:04 917510 /home/zensiert/src/a.out 00601000-00602000 r--p 00001000 09:04 917510 /home/zensiert/src/a.out 00602000-00603000 rw-p 00002000 09:04 917510 /home/zensiert/src/a.out 010be000-010df000 rw-p 00000000 00:00 0 [heap] 2b22ccfc3000-2b22ccfe2000 r-xp 00000000 09:02 5044 /lib/ld-2.10.1.so 2b22ccfe2000-2b22ccfe6000 rw-p 00000000 00:00 0 2b22cd1e1000-2b22cd1e2000 r--p 0001e000 09:02 5044 /lib/ld-2.10.1.so 2b22cd1e2000-2b22cd1e3000 rw-p 0001f000 09:02 5044 /lib/ld-2.10.1.so 2b22cd1e3000-2b22cd2d5000 r-xp 00000000 09:02 131242 /usr/lib/libstdc++.so.6.0.13 2b22cd2d5000-2b22cd4d5000 ---p 000f2000 09:02 131242 /usr/lib/libstdc++.so.6.0.13 2b22cd4d5000-2b22cd4dc000 r--p 000f2000 09:02 131242 /usr/lib/libstdc++.so.6.0.13 2b22cd4dc000-2b22cd4de000 rw-p 000f9000 09:02 131242 /usr/lib/libstdc++.so.6.0.13 2b22cd4de000-2b22cd4f3000 rw-p 00000000 00:00 0 2b22cd4f3000-2b22cd575000 r-xp 00000000 09:02 5051 /lib/libm-2.10.1.so 2b22cd575000-2b22cd775000 ---p 00082000 09:02 5051 /lib/libm-2.10.1.so 2b22cd775000-2b22cd776000 r--p 00082000 09:02 5051 /lib/libm-2.10.1.so 2b22cd776000-2b22cd777000 rw-p 00083000 09:02 5051 /lib/libm-2.10.1.so 2b22cd777000-2b22cd78d000 r-xp 00000000 09:02 9996 /lib/libgcc_s.so.1 2b22cd78d000-2b22cd98c000 ---p 00016000 09:02 9996 /lib/libgcc_s.so.1 2b22cd98c000-2b22cd98d000 r--p 00015000 09:02 9996 /lib/libgcc_s.so.1 2b22cd98d000-2b22cd98e000 rw-p 00016000 09:02 9996 /lib/libgcc_s.so.1 2b22cd98e000-2b22cd98f000 rw-p 00000000 00:00 0 2b22cd98f000-2b22cdaf5000 r-xp 00000000 09:02 5047 /lib/libc-2.10.1.so 2b22cdaf5000-2b22cdcf4000 ---p 00166000 09:02 5047 /lib/libc-2.10.1.so 2b22cdcf4000-2b22cdcf8000 r--p 00165000 09:02 5047 /lib/libc-2.10.1.so 2b22cdcf8000-2b22cdcf9000 rw-p 00169000 09:02 5047 /lib/libc-2.10.1.so 2b22cdcf9000-2b22cdd00000 rw-p 00000000 00:00 0 7fffb0297000-7fffb02ac000 rw-p 00000000 00:00 0 [stack] 7fffb02e0000-7fffb02e1000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Abort
-
@ SeppJ: Genau so meinte ich das! Sehr schön

@ krümelkacker: Danke
Gruß
-
theliquidwave schrieb:
char *pszBla = new char[32]; strcpy(pszBla, "das hier ist ja auch ein literal"); // ... delete[] pszBla; // pszBla ist nun gelöscht (der char*), aber das Literal existiert noch, richtig?pszBla ist ein Zeiger der automatisch aufhört zu existieren, und zwar genau dann, wenn die nächste schließende }-Klammer kommt. Was Du über delete[] löschst, ist das, worauf der Zeiger zeigt, nämlich ein dynamisch angelegtes char-Array.
Das mit den String-Literale kannst Du dir so vorstellen:
#include <iostream> int main() { std::cout << "Hallo Welt!\n"; }ist im Prinzip das Gleiche wie
#include <iostream>
const char literal001[] = "Hallo Welt!\n";
int main() {
std::cout << literal001;
}
[/cpp]
Der Unterschied ist allerdings, dass das Literal in Wirklichkeit keinen Namen besitzt. Der Compiler darf auch String-Literale mehrfach wiederbenutzen, wenn er so schlau ist. Beispiel:#include <iostream> int main() { std::cout << "Hallo Welt!\n"; std::cout << "Welt!\n"; }darf von einem Compiler auch so übersetzt werden wie
#include <iostream>
const char literal001[] = "Hallo Welt!\n";
int main() {
std::cout << literal001;
std::cout << (literal001+6);
}
[/cpp]
-
Recht interessant Sepp, nur das ich davon gar nichts verstehe

Und danke für die ausführliche Erklärung @ krümelkacker
Gruß