Responda
Explique, em pormenores, o seguinte pedaço de código:
int x = GetInt();
int array[ ] = malloc( x*sizeof(int));
Explique, em pormenores, o seguinte pedaço de código:
int x = GetInt();
int array[ ] = malloc( x*sizeof(int));
Passo 1
O enunciado apresenta duas linhas de código em C que, na prática, leem um valor inteiro da entrada e, em seguida, usam esse valor para alocar dinamicamente um vetor de inteiros. O conteúdo principal é leitura de dados pelo usuário e alocação de memória em tempo de execução usando
malloc. Para resolver, vamos ver o que cada função/função– macro faz, qual é o tipo de cada variável e quais cuidados devemos ter ao usar memória dinâmica.Passo 2
Analisando a linha
int x \(=\) GetInt();
– Aqui ) uma função que lê um inteiro digitado pelo usuário e o retorna.
– Declaramos
– A partir de agora,
GetInt() é (por exemplo, na biblioteca CS
– Declaramos
x como int e atribuímos a esse nome o valor que o usuário informou.– A partir de agora,
x contém o tamanho desejado para o nosso vetor de inteiros.Passo 3
Agora a linha
int array[] \(=\) malloc(x * sizeof(int));
é sintaticamente incorreta em C puro, pois não se pode inicializar um VLA (Variable Length Array) com um ponteiro. O que se pretendia provavelmente era:
int *array \(=\) malloc(x * sizeof(int));
–
– O argumento
– Fazendo o cast implícito para
malloc retorna um ponteiro genérico (void *) para um bloco contíguo de memória com tamanho em bytes igual ao argumento.– O argumento
x * sizeof(int) calcula quantos bytes são necessários para armazenar x elementos do tipo int.– Fazendo o cast implícito para
int *, array passa a apontar para o início desse bloco de memória no heap.Passo 4
Detalhando o cálculo de tamanho:
– bytes).
– Multiplicar por
–
sizeof(int) devolve quantos bytes o compilador reserva para um inteiro naquela plataforma (por exemplo,
– Multiplicar por
x faz com que o total de bytes seja suficiente para x inteiros seguidos.Passo 5
Após a chamada a
malloc, é fundamental checar se a alocação foi bem-sucedida:Sem essa verificação, tentar usar
array[i] em caso de retorno NULL provocará acessos inválidos à memória.Passo 6
Depois de usar o vetor (inserir valores, processá-los etc.), não podemos esquecer de liberar a memória alocada:
free(array);
Isso evita vazamentos de memória (memory leaks) quando o programa continua rodando ou chama várias alocações.
Resposta
O trecho inteiro faz o seguinte:
. Lê um valor inteiro
. Usa
. Armazena o ponteiro para esse bloco em
. Cabe ao programador verificar
x do usuário.malloc(x * sizeof(int)) para reservar dinamicamente um bloco com espaço para x inteiros.array (deve ser int *array).array !\(=\) NULL antes de usar e chamar free(array) depois de terminar.