C ++ char array [] vazamento de memória [duplicado]
Eu criei char arr [] e atribuí a ele literal de string
char arr[] = "some string"; // arr occupies 12 chars in memory
std::cout << std::strlen(arr) << std::endl; // lenght is 11 chars + 1 null-terminator
//arr[11] is '\0'
em seguida, coloco terminador nulo em 6 elementos
arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars + 1 null-terminator
- É vazamento de memória?
- Como o compilador saberá que deve liberar memória depois de '\ 0'? (quando irá deletar a variável arr)
- É possível alterar o comprimento desta variável arr e notificar o compilador quanto ela deve liberar ao excluir a variável?
Respostas
- É vazamento de memória?
Não.
- Como o compilador saberá que deve liberar memória depois de '\ 0'? (quando irá deletar a variável arr)
A variável é 12 caracteres. É o mesmo que escrever:
char arr[12] = "some string";
Portanto, sempre liberará 12 caracteres. A variável é uma matriz de 12 caracteres; o fato de o 6º caractere ser '\ 0' é completamente irrelevante.
A propósito, depois de definir o 6º caractere como '\ 0', você ainda pode usar todos os 12 caracteres, porque ainda é um array de 12 caracteres. Mesmo aqueles após o '\ 0'. Mas você não pode armazenar 13 caracteres nele.
- É possível alterar o comprimento desta variável arr e notificar o compilador quanto ela deve liberar ao excluir a variável?
Não. Não é possível alterar o tamanho de nenhuma variável.
Neste código:
char arr[] = "some string";
a variável arr
é um array estático com tamanho fixo. Não há alocação de memória dinâmica aqui e, portanto, não há necessidade de se preocupar com vazamentos de memória. O compilador cuidará da memória, independentemente do que você escrever arr
.
Para completar.
Também não há vazamento de memória na memória alocada, como em:
char* arr = (char*) malloc(12);
strcpy(arr, "some string");
arr[6] = '\0';
free(arr);
O gerenciamento de memória é feito pela memória alocada (12), não pelo uso subjacente (char * nul-terminado). (Estilo C, C ++ da mesma forma)
Parece que você entendeu ao contrário. O tamanho da matriz em C ++ não pode ser alterado, ponto final. Devido a esse fato e ao fato de que se você passar array como um ponteiro, você perde informações do tamanho real daquele acordo de array foi criado para strings de estilo C - 0 byte também \0
conhecido como terminador nulo tratado como extremidade dinâmica da string. Acordo significa que funções que trabalham com strings de estilo C tratam isso como terminação de string. Isso permite que você use um array de tamanho fixo para strings de comprimento diferente e passe apenas um ponteiro sem tamanho de memória real para funções para ler a partir dele (por exemplo, imprimir na tela). Observe, quando você passa o array char para funções que gravam dados nele, você geralmente precisa dizer qual é o tamanho real do array, para que a função não acesse a memória fora dos limites, pois essas funções ignorariam o terminador nulo se ele já estiver lá.
É isso, esse acordo acontece nas diferentes camadas gerenciadas pelos arrays. Portanto, quaisquer dados que você colocar nesse array não afetarão seu tamanho do ponto de vista da linguagem, para o compilador C ++ você criou um array de tamanho fixo, você coloca alguns dados nele e quando seu tempo de vida chega ao fim, o compilador o destrói como um array inteiro de tamanho fixo. Não importa se você colocou zero byte lá ou não.
Um vazamento de memória ocorre quando uma memória foi alocada pelo programador usando o operador new
e não foi excluída usando o operador delete
ou delete []
.
Nesta declaração
char arr[] = "some string";
É a memória alocada do compilador (ou do sistema) para o array de caracteres arr que tem a duração do armazenamento automático ou estático. Portanto, o compilador (ou o sistema) é responsável por liberar a memória alocada. O endereço da memória alocada é conhecido pelo compilador (ou sistema).
Usando esta declaração
arr[5] = '\0';
você não realocou a matriz. Você acabou de alterar seu conteúdo mais precisamente apenas um de seu byte.
Como o compilador saberá que deve liberar memória depois de '\ 0'? (quando irá deletar a variável arr)
Porque o compilador (ou sistema) sabe como o objeto do tipo array foi declarado.
Para o objeto foram alocados 12 bytes.
char arr[] = "some string";
É possível alterar o comprimento desta variável arr e notificar o compilador quanto ela deve liberar ao excluir a variável?
Acho que você quer dizer o tamanho do objeto. Não, você não pode alterar o tamanho do objeto porque não foi você quem alocou a memória para o objeto.
Você poderia realocar o objeto se você usou o operador new
para alocá-lo como por exemplo
char *arr = new char[12];
std::strcpy( arr, "some string" );
//...
char *tmp = new char[20];
strcpy( tmp, "another " );
strcat( tmp, arr );
delete [] arr;
arr = tmp;