Há necessidade de destruir char * = “string” ou char * = new char[6]?
Pergunta
Eu assumo isso char* = "string"
é o mesmo que char* = new char[6]
.Acredito que essas strings são criadas na pilha e não na pilha.Então, preciso destruí-los ou liberar sua memória quando terminar de usá-los ou eles serão destruídos sozinhos?
Solução
Não.Você só precisa liberar strings manualmente ao alocar manualmente a memória usando o método malloc
função (em C) ou o new
operador (em C++).Se você não usar malloc
ou new
, então o char*
ou string será criada na pilha ou como uma constante em tempo de compilação.
Outras dicas
Não.Quando voce diz:
const char* c = "Hello World!";
Você está atribuindo c a uma constante de string "pré-existente" que NÃO é a mesma que:
char* c = new char[6];
Somente neste último caso você está alocando memória no heap.Então você chamaria delete quando terminar.
Presumo que quando o faço
char* = "string"
é a mesma coisa quechar* = new char[6]
.
Não.O que o primeiro faz é criar uma constante.Modificá-lo é um comportamento indefinido.Mas para responder sua pergunta;não, você não precisa destruí-los.E só uma nota, use sempre std::string
quando possível.
O nome do jogo é “destrua apenas o que você criou”.Aqui estão os pares:
malloc
/free
calloc
/free
new
/delete
new []
/delete []
Desde que você criou a segunda string usando new []
, a responsabilidade recai sobre você para destruí-lo com delete []
.Chamar delete [] string2
Quando tiver terminado.
Agora, se o seu código for complicado o suficiente e dificultar o controle das exclusões, considere o uso de ponteiros com escopo ou ponteiros automáticos.O boost::scoped_ptr
class da biblioteca boost é um bom lugar para começar.Veja também o RAII idioma, coisas muito úteis e úteis.
Eles não são iguais.Seu primeiro exemplo é uma string constante, portanto definitivamente não é alocada no heap.Seu segundo exemplo é uma alocação de memória de tempo de execução de 6 caracteres, e isso vem do heap.Você não deseja excluir seu primeiro exemplo, mas precisa delete []
seu segundo exemplo.
Você não sabe onde os literais de string estão armazenados.Pode até ser memória somente leitura, então seu código deve ser:
const char* c = "string";
E um novo matriz de caracteres deve ser excluird como qualquer outra área de memória alocada dinamicamente.
new é sempre uma alocação, enquanto a definição de uma string inline na verdade incorpora os dados no próprio programa e não pode ser alterada (alguns compiladores permitem isso por meio de um truque inteligente, não se preocupe).
Alguns compiladores digitam strings embutidas para que você não possa modificar o buffer.
char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
Vamos ver o que o GCC 4.8 x86-64 Linux faz
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 e descompilar:
g++ -ggdb -std=c++98 a.cpp
objdump -CSr a.o
A saída contém:
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)
Interpretação:
char *s = "abc"
entra.rodata
.Então você não podefree
isso de qualquer maneira.char *sn = new char[4];
vem da saída deoperator new[]
.Portanto, você deve liberá-lo quando puder.