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.