Pular para o conteúdo principal

Questão de Programação — Programação estruturada — FUNDATEC 2026

ProgramaçãoProgramação estruturada
Código
qg685271
Banca
FUNDATEC
Órgão
IFC-SC
Ano
2026
Nível
Superior
Cargo
Professor EBTT - Informática: Linguagens de Programação
Analise o seguinte programa escrito em linguagem C conforme o padrão ANSI C:Imagem associada para resolução da questãoConsiderando o comportamento definido pelo padrão ANSI C para alocação e liberação de memória dinâmica, assinale a alternativa que descreve corretamente a execução do programa.
  1. AO programa imprime 20, pois o valor armazenado em b permanece acessível após free.
  2. BO programa imprime 30, pois p passa automaticamente a apontar para c.
  3. CO programa apresenta comportamento indefinido, pois p passa a referenciar memória já liberada.
  4. DO programa imprime 10, pois p passa a apontar para a.
  5. EO programa não executa a instrução printf.
Revelar gabarito e comentário

GabaritoC — O programa apresenta comportamento indefinido, pois p passa a referenciar memória já liberada.

Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.

Memória dinâmica em C: ponteiros e free()

Gabarito: letra C. Após a chamada de free(p), o ponteiro p continua armazenando o endereço da região de memória que foi liberada — mas essa região não pertence mais ao programa, e qualquer acesso a ela (leitura ou escrita) configura comportamento indefinido (undefined behavior) segundo o padrão ANSI C. É exatamente isso que a alternativa C descreve.

O que está em jogo aqui é o conceito de ponteiro pendente (dangling pointer). Quando você aloca memória com malloc(), recebe um endereço válido. Ao chamar free(), você devolve aquela região ao sistema — o ponteiro, porém, não é automaticamente anulado; ele continua guardando o endereço antigo. A partir desse momento, o valor armazenado naquela região pode ser alterado por qualquer outra alocação, ou a página pode ser desalocada pelo sistema operacional. Ler ou escrever através desse ponteiro é um erro de programação clássico, e o padrão C não define o que acontece: pode imprimir o valor antigo, pode imprimir lixo, pode causar um crash — tudo é possível. Por isso o termo técnico é comportamento indefinido.

Vamos pensar num exemplo concreto. Suponha que você aloque espaço para um inteiro e guarde o valor 20 nele:

int *p = malloc(sizeof(int));
*p = 20;
free(p);
printf("%d\n", *p);  // comportamento indefinido!

O printf pode imprimir 20 (se a memória ainda não foi reutilizada), pode imprimir um número aleatório, ou o programa pode simplesmente abortar. Nenhum desses resultados é garantido — e é justamente essa imprevisibilidade que a banca explora. A alternativa A, por exemplo, afirma que o programa "imprime 20, pois o valor permanece acessível após free" — isso é uma suposição incorreta: o valor pode até continuar lá por acaso, mas não há garantia alguma, e o padrão não define esse comportamento.

Outro ponto importante: free() não faz o ponteiro apontar para outro lugar. Ele apenas libera a memória. A alternativa B diz que "p passa automaticamente a apontar para c" — isso não acontece. O ponteiro continua com o mesmo endereço; o que muda é que aquele endereço deixa de ser válido para o programa. A alternativa D, por sua vez, afirma que "p passa a apontar para a" — também incorreto, pela mesma razão: nenhuma realocação automática ocorre.

A pegadinha central desta questão é a ilusão de que o valor continua acessível. Muitos candidatos, ao executarem mentalmente o código, veem que o valor ainda está lá e marcam a alternativa A. Mas a pergunta é sobre o que o padrão ANSI C define — e o padrão define que acessar memória liberada é comportamento indefinido, independentemente do que aconteça na prática em um compilador específico. Guarde essa distinção: o que acontece na prática ≠ o que o padrão garante.

NÃO CAIA NESSA!

A banca explora a diferença entre o que parece acontecer e o que o padrão define. A alternativa A é a mais tentadora: o valor 20 pode realmente ser impresso em muitos compiladores, mas isso é mero acaso — o padrão ANSI C não garante nada após free(). A resposta correta é sempre a que menciona comportamento indefinido.

  1. 1malloc() aloca região
  2. 2Ponteiro guarda endereço
  3. 3free() libera região
  4. 4Ponteiro continua com endereço
  5. 5Acesso → comportamento indefinido
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

Afirma que o programa imprime 20 porque o valor permanece acessível após free(). O erro está em tratar como garantido algo que é apenas possível: após a liberação, a memória pode ser reutilizada ou desalocada, e o valor pode ser corrompido. O padrão C não assegura que o valor continue lá — acessar essa região é comportamento indefinido.

Alternativa B — ❌ Incorreta

Diz que o programa imprime 30 porque p passa automaticamente a apontar para c. Isso não ocorre: free() apenas libera a memória apontada por p; o ponteiro não é redirecionado para nenhuma outra variável. O endereço armazenado em p permanece o mesmo, mas deixa de ser válido.

Alternativa C — ✅ Correta ⟵ GABARITO

Descreve com precisão o que acontece: após free(p), o ponteiro p referencia memória já liberada, e qualquer acesso a ela configura comportamento indefinido segundo o padrão ANSI C. É a única alternativa que reflete corretamente a semântica da linguagem.

Alternativa D — ❌ Incorreta

Afirma que o programa imprime 10 porque p passa a apontar para a. Assim como na alternativa B, não há redirecionamento automático do ponteiro após free(). O ponteiro continua apontando para a região liberada, não para outra variável.

Alternativa E — ❌ Incorreta

Diz que o programa não executa a instrução printf. Não há nada no código que impeça a execução do printf — a instrução é alcançada normalmente. O problema não é a execução, mas o fato de ela acessar memória inválida, o que gera comportamento indefinido.

Gabarito: letra C

Link permanente: /questoes/qg685271