💻 Exemplos: Capítulo 08: Ponteiros Brutos, Aritmética de Endereços e Alinhamento
💻 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.