Ponteiros

Se você quer escrever código que modifica diretamente a memória da máquina, vai ter que entender ponteiros. Eles não são um tipo especial - são apenas variáveis que armazenam endereços de memória. Mas com isso, você pode acessar, modificar ou interpretar qualquer região de memória do processo. Literalmente.

O que é um ponteiro?

int x = 10; 
int *px = &x;
  • x é uma variável com um valor (10).

  • &x é o endereço de memória onde x está guardado.

  • px é um ponteiro para inteiro, ou seja, ele guarda o endereço de x.

Você pode acessar o valor apontado com o operador de desreferência:

printf("%d\n", *px); // imprime 10

Ponteiros são números

Ponteiros são representados como endereços inteiros, normalmente de 4 bytes (32 bits) ou 8 bytes (64 bits), dependendo da arquitetura. São exibidos em hexadecimal:

printf("%p\n", (void *)px); // Ex: 0x7ffeebf5a4cc

Isso é o que permite aritmética de ponteiros, interpretação de dados arbitrários, e técnicas como type punning, casting bruto ou exploração de estruturas de dados.

Aritmética de ponteiros

int arr[3] = {10, 20, 30}; 
int *p = arr; 

printf("%d\n", *(p + 1)); // 20

Ao fazer p + 1, o endereço avança sizeof(int)` bytes, não 1 byte. Isso funciona com qualquer tipo de dado.

Ponteiros e arrays

Arrays são ponteiros disfarçados:

  • arr é um ponteiro para o primeiro elemento.

  • arr[i] é sintaxe equivalente a *(arr + i).

Isso tem implicações profundas quando você passa arrays para funções - na verdade, você passa um ponteiro.

Ponteiro para ponteiro

Você pode ter ponteiros que apontam para ponteiros, criando níveis de indireção. Isso é comum em:

  • Matrizes dinâmicas (char **argv)

  • Manipulação de ponteiros genéricos

  • Passagem de ponteiros por referência

Ponteiros void e casting

void * é um ponteiro genérico, sem tipo associado. Você precisa fazer casting para usá-lo:

Muito comum em funções de alocação e estruturas de dados genéricas.

Ponteiros e structs

Você pode usar -> para acessar membros quando estiver usando um ponteiro para struct.

Perigos reais: dangling, wild e null pointers

  • Dangling pointer: aponta para algo que já foi liberado

  • Wild pointer: ponteiro não inicializado (valor indefinido)

  • Null pointer: ponteiro que aponta para NULL (0x0)

Erros com ponteiros são causa frequente de falhas críticas, undefined behavior e brechas de segurança.

Ponteiros são a base de...

  • Manipulação direta de memória (memcpy, buffers)

  • Estruturas como listas, árvores e grafos

  • Análise de binários (interpretação manual de estruturas)

  • Engenharia reversa (reconhecimento de padrões em ponteiros)

  • Exploração de software (buffer overflows, use-after-free)

Last updated