2008-09-09 9 views

Respuesta

31

No. Solo necesita liberar cadenas manualmente cuando asigne manualmente la memoria mediante la función malloc (en C) o el operador new (en C++). Si no usa malloc o new, se creará char* o una cadena en la pila o como una constante de tiempo de compilación.

1

No sabe dónde se almacenan los literales de cadena. Incluso puede ser la memoria de sólo lectura, por lo que su código debe decir:

const char* c = "string"; 

Y una nueva matriz carbón debe ser eliminar d al igual que cualquier otra área de memoria asignada dinámicamente.

4

No son lo mismo. Su primer ejemplo es una cadena constante, por lo que definitivamente no se asigna desde el montón. Su segundo ejemplo es una asignación de memoria de tiempo de ejecución de 6 caracteres, y eso proviene del montón. No desea eliminar su primer ejemplo, pero necesita delete [], su segundo ejemplo.

+1

"nuevo" asigna memoria del montón, nunca de la pila. (A menos que, por supuesto, haya anulado el nuevo operador.) –

+0

Mi mal. Lo sabía. De Verdad. :-) – Andrew

+0

Luego amablemente editar;) – FordFulkerson

4

Supongo que cuando hago char* = "string" es lo mismo que char* = new char[6].

No. Lo que hace el primero es crear una constante. Modificarlo es un comportamiento indefinido. Pero para responder a tu pregunta; no, no tienes que destruirlos. Y solo una nota, siempre use std::string siempre que sea posible.

0

nuevo es siempre una asignación, mientras que la definición de una cadena en línea realmente integra los datos en el programa y no se puede cambiar (algunos compiladores lo permiten mediante un truco inteligente, no se moleste).

Algunos compiladores escriben cadenas en línea para que no pueda modificar el búfer.

char* const sz1 = "string"; // embedded string, immutable buffer 
char* sz2 = new char[10]; // allocated string, should be deleted 
17

No. Cuando usted dice:

const char* c = "Hello World!"; 

está asignando c para una constante de cadena "preexistente", que no es lo mismo que:

char* c = new char[6]; 

Sólo en el este último caso está asignando memoria en el montón. Entonces llamarías a eliminar cuando hayas terminado.

3

El nombre del juego es "destruir solo lo que has creado".Aquí están las parejas:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. new []/delete []

Desde que creó la segunda cadena utilizando new [], la responsabilidad está en ti para destruirlo con delete []. Llame al delete [] string2 cuando haya terminado.

Ahora, si su código es lo suficientemente intrincado y hace que sea difícil hacer un seguimiento de las eliminaciones, tenga en cuenta el uso de punteros de ámbito o punteros automáticos. La clase boost::scoped_ptr de la biblioteca de impulso es un buen lugar para comenzar. También busque en el idioma RAII, bastante útil y útil.

0

Vamos a ver lo que hace GCC 4.8 x86-64 Linux

Programa:

#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); 
} 

Compilar y descompilar:

g++ -ggdb -std=c++98 a.cpp 
objdump -CSr a.o 

la salida contiene:

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) 

Interpretación:

  • char *s = "abc" entra en .rodata. Entonces no puedes free de ninguna manera.
  • char *sn = new char[4]; viene de la salida operator new[]. Entonces deberías liberarlo cuando puedas.