Ponteiros, Vida Útil e Posse¶
Segurança de memória em C++ exige mais que ponteiro não nulo. Ponteiro ou referência deve designar objeto cuja vida começou, não terminou e permite a operação.
Armazenamento e vida do objeto¶
Armazenamento fornece bytes alinhados. A vida começa e termina por construção, destruição e regras da linguagem. O armazenamento pode sobreviver ao objeto, e um ponteiro continuar não nulo após o fim.
Desreferenciar o resultado é comportamento indefinido. O defeito é de vida útil.
Prefira valores e proprietários com escopo¶
std::vector<widget> values; // owns widget values
auto owner = std::make_unique<widget>(); // exclusive dynamic owner
widget& alias = *owner; // non-owning; owner must outlive use
Alocação dinâmica não é exigida só porque o objeto é grande. Use-a quando vida em runtime, polimorfismo, endereço estável, grafo ou requisito explícito exigir indireção.
Aritmética de ponteiros¶
É definida somente dentro de um array e na posição one-past. Esta pode ser
comparada ou usada como sentinela, não desreferenciada. Prefira iteradores, ranges
e std::span a pares ponteiro-comprimento.
Contratos de posse¶
| Interface | Significado |
|---|---|
T |
Valor independente |
T& / T const& |
Alias obrigatório sem posse |
T* / T const* |
Alias opcional/reposicionável sem posse |
std::unique_ptr<T> |
Transferência de posse exclusiva |
std::shared_ptr<T> |
Posse compartilhada |
std::weak_ptr<T> |
Observação sem posse compartilhada |
std::span<T> |
Intervalo contíguo sem posse |
Tipos não codificam toda vida útil. Uma referência ainda pode ficar dangling.
Invalidação¶
Operações de contêiner invalidam iteradores, ponteiros, referências e views. A realocação de vector invalida todas as referências aos elementos. Leia o contrato específico.
Alocação manual¶
Pares new/delete e new[]/delete[] falham sob retornos antecipados,
exceções e transferências. Encapsule em contêineres, smart pointers, allocators ou recursos auditados.
Exercícios¶
- Identifique dependências de vida em classe com
std::string_view. - Explique por que ponteiro não nulo ainda pode ser inválido.
- Refatore buffer
new[]/delete[]parastd::vector.