💻 Exemplos: Capítulo 08: Ponteiros Brutos, Aritmética de Endereços e Alinhamento

Especialização em Sistemas com C++ • Demonstrações Práticas Compiláveis


🎯 Objetivo dos Exemplos

Apresentar os fundamentos de baixo nível da arquitetura Von Neumann em C++: operação com endereços brutos de memória, segurança do literal nullptr, desreferenciação, aritmética de ponteiros baseada no tamanho do tipo (stride), verificação de alinhamento natural com alignof e diferenciação física entre Stack e Heap.


1. Código Fonte Completo (main.cpp)

/**
 * @file main.cpp
 * @brief Ponteiros brutos, aritmética de strides e inspeção de layout de memória.
 */

#include <iostream>
#include <cstdint>
#include <iomanip>

struct RegistroDispositivo {
    std::uint32_t canal_id; // 4 bytes
    std::uint16_t codigo;   // 2 bytes
    // 2 bytes de padding gerados pelo compilador para alinhamento de 4 bytes
    float         voltagem; // 4 bytes
};

int main() {
    std::cout << "=== CAPÍTULO 08: PONTEIROS BRUTOS E ENDEREÇAMENTO ===" << '\n';

    // 1. Variável na Stack vs Variável no Heap
    int stack_var = 42;
    int* heap_ptr = new int(100); // Alocação manual crua (para análise de endereço)

    std::cout << "Endereco na Stack (&stack_var): " << static_cast<void*>(&stack_var) << '\n';
    std::cout << "Endereco no Heap (heap_ptr):   " << static_cast<void*>(heap_ptr) << '\n';
    std::cout << "Diferenca de regiao (Stack decresce/Heap cresce segundo o SO)\n";

    // 2. Alinhamento de Memória e Padding
    std::cout << "\n--- Inspeção de Alinhamento e Tamanho de RegistroDispositivo ---" << '\n';
    std::cout << "sizeof(RegistroDispositivo):  " << sizeof(RegistroDispositivo) << " bytes" << '\n';
    std::cout << "alignof(RegistroDispositivo): " << alignof(RegistroDispositivo) << " bytes" << '\n';

    // 3. Aritmética de Ponteiros (Passo baseado no tamanho do tipo)
    int numeros[4] = { 10, 20, 30, 40 };
    int* ptr_inicio = numeros;

    std::cout << "\n--- Aritmética de Ponteiros ---" << '\n';
    for (int i = 0; i < 4; ++i) {
        // ptr_inicio + i incrementa (i * sizeof(int)) bytes fisicos na RAM
        std::cout << "Elemento [" << i << "] -> Endereco: " 
                  << static_cast<void*>(ptr_inicio + i)
                  << " | Valor: " << *(ptr_inicio + i) << '\n';
    }

    // 4. Distância entre Ponteiros (ptrdiff_t)
    int* ptr_fim = &numeros[3];
    std::ptrdiff_t distancia = ptr_fim - ptr_inicio;
    std::cout << "Distancia de elementos entre primeiro e ultimo: " << distancia << '\n';

    // 5. Limpeza Obrigatória e Proteção de Ponteiro Pendente (Dangling Pointer)
    delete heap_ptr;
    heap_ptr = nullptr; // Essencial para evitar corrupção de memória por Use-After-Free

    if (heap_ptr == nullptr) {
        std::cout << "\nheap_ptr devidamente desreferenciado e aterrado como nullptr." << '\n';
    }

    return 0;
}

2. Instruções de Compilação e Execução

# Compilação com GCC / Clang
g++ -std=c++20 -Wall -Wextra -O2 main.cpp -o app_ponteiros
./app_ponteiros

# Compilação com MSVC
cl /std:c++20 /EHsc /W4 /O2 main.cpp /Fe:app_ponteiros.exe
.\app_ponteiros.exe

3. Saída Esperada no Terminal

=== CAPÍTULO 08: PONTEIROS BRUTOS E ENDEREÇAMENTO ===
Endereco na Stack (&stack_var): 0x7ffd19b38034
Endereco no Heap (heap_ptr):   0x55dc9249eeb0
Diferenca de regiao (Stack decresce/Heap cresce segundo o SO)

--- Inspeção de Alinhamento e Tamanho de RegistroDispositivo ---
sizeof(RegistroDispositivo):  12 bytes
alignof(RegistroDispositivo): 4 bytes

--- Aritmética de Ponteiros ---
Elemento [0] -> Endereco: 0x7ffd19b38040 | Valor: 10
Elemento [1] -> Endereco: 0x7ffd19b38044 | Valor: 20
Elemento [2] -> Endereco: 0x7ffd19b38048 | Valor: 30
Elemento [3] -> Endereco: 0x7ffd19b3804c | Valor: 40
Distancia de elementos entre primeiro e ultimo: 3

heap_ptr devidamente desreferenciado e aterrado como nullptr.