C ++ char array [] vazamento de memória [duplicado]

Aug 18 2020

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
  1. É vazamento de memória?
  2. Como o compilador saberá que deve liberar memória depois de '\ 0'? (quando irá deletar a variável arr)
  3. É possível alterar o comprimento desta variável arr e notificar o compilador quanto ela deve liberar ao excluir a variável?

Respostas

5 user253751 Aug 18 2020 at 13:03
  1. É vazamento de memória?

Não.

  1. 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.

  1. É 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.

6 cigien Aug 18 2020 at 13:03

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.

2 JoopEggen Aug 18 2020 at 13:07

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)

1 Slava Aug 18 2020 at 13:56

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 \0conhecido 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.

VladfromMoscow Aug 18 2020 at 13:16

Um vazamento de memória ocorre quando uma memória foi alocada pelo programador usando o operador newe não foi excluída usando o operador deleteou 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 newpara 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;