Qual o problema da função troca abaixo?
void troca (int *i, int *j) {
    int *temp;
    *temp = *i;
    *i = *j;
    *j = *temp;
}

Passo 1

O enunciado dá uma função em C e pergunta qual é o problema dela. O código fornecido é:
void troca (int *i, int *j) {
    int *temp;
    *temp = *i;
    *i = *j;
    *j = *temp;
}
O que se quer saber: qual é o erro desse código e por que ele está errado.

Passo 2

O que a função deveria fazer (intuição): trocar os valores inteiros armazenados nas posições apontadas por i e j. Ou seja, se i aponta para uma variável a com valor 3 e j aponta para uma variável b com valor 5, após a chamada troca(&a,&b) espera-se a == 5 e b == 3.

Passo 3

Noções básicas de ponteiros e desreferência (explicação didática)
  • Um int *p é uma variável que guarda um endereço de memória onde há um int.
  • *p é a operação de desreferenciar: acessar o inteiro que está no endereço guardado em p.
  • Antes de usar *p (ler ou escrever), p deve conter um endereço válido (por exemplo, o endereço de uma variável existente, como &a). Se p não foi inicializado, ele contém “lixo” — um endereço qualquer — e usar *p leva a comportamento indefinido (pode travar o programa, sobrescrever memória, etc.).

Passo 4

Identificação precisa do erro no código
  • A linha int *temp; declara temp como um ponteiro para int, mas não inicializa esse ponteiro. temp passa a conter um endereço indeterminado.
  • Em seguida o código faz *temp = *i;. Isso tenta escrever no endereço armazenado em temp. Como temp não foi inicializado, isso escreve em um endereço arbitrário: comportamento indefinido (possível segmentation fault ou corrupção de memória).
  • Portanto o problema é que está sendo desreferenciado um ponteiro não inicializado.

Passo 5

Como consertar (solução típica e explicação passo a passo)
  • O objetivo é guardar temporariamente o valor inteiro apontado por i. Para isso não é preciso um ponteiro; precisa-se de um int temporário que guarde o valor.
  • Correção correta:
void troca (int *i, int *j) {
    int temp;     // temp guarda o valor inteiro, não um endereço
    temp = *i;    // temp recebe o valor apontado por i
    *i = *j;      // posição de i recebe o valor apontado por j
    *j = temp;    // posição de j recebe o valor guardado em temp
}
Explicando linha a linha com exemplo numérico:
  • Suponha a = 3 em endereço 0x100 e b = 5 em endereço 0x200, i = &a, j = &b.
  • int temp; cria uma variável temp local na pilha.
  • temp = *i;*i (valor 3) e armazena em temp (agora temp == 3).
  • *i = *j;*j (valor 5) e escreve em *i (agora a == 5).
  • *j = temp; escreve temp (que é 3) em *j (agora b == 3).
  • Resultado: a == 5 e b == 3, troca feita corretamente.

Passo 6

Outra possibilidade (trocar os ponteiros em vez dos valores)
  • Se a intenção fosse trocar os próprios ponteiros (ou seja, fazer i apontar para o que j apontava e vice-versa), a assinatura da função precisa receber ponteiros para ponteiros:
void troca_ptrs(int **pi, int **pj) {
    int *temp;
    temp = *pi;
    *pi = *pj;
    *pj = temp;
}
  • Aqui pi e pj são endereços de variáveis do tipo int *, então *pi é um int *. Esse código troca endereços; não confundir com trocar os valores apontados.

Passo 7

Resumo de segurança e boas práticas rápidas
  • Sempre inicialize ponteiros antes de desreferenciá-los.
  • Para trocar valores, use uma variável temporária do tipo do valor (aqui int temp).
  • Verifique se os ponteiros de entrada não são NULL (opcional, dependendo do contrato da função):
if (i == NULL || j == NULL) return;
  • Comentários e exemplos ajudam a evitar confusões entre “trocar valores” e “trocar ponteiros”.

Resposta

O problema é que temp foi declarado como int *temp; e nunca inicializado, sendo depois desreferenciado com *temp — isso causa comportamento indefinido. A correção usual é declarar int temp; e usar temp = *i; *i = *j; *j = temp;.