Memória Stack vs. Heap
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 12 de 104.
Os programas em C++ usam duas regiões principais de memória: a pilha e o heap. Entender onde seus objetos ficam é crucial para escrever um código eficiente e livre de bugs.
A stack é uma memória rápida e automática. As variáveis declaradas dentro das funções vivem aqui e são destruídas automaticamente quando saem do escopo.
void example() {
int x = 10; // Alocação na stack
Player player; // Alocação na stack - destruído automaticamente
} // x e player são destruídos aquiA heap é uma memória maior, porém mais lenta, que você gerencia manualmente. Os objetos na heap persistem até que você os exclua explicitamente.
void example() {
Player* player = new Player(); // Alocação na heap
// player existe até ser deletado
delete player; // Limpeza manual necessária
}Principais diferenças:
| Pilha | Heap |
|---|---|
| Alocação rápida | Alocação mais lenta |
| Tamanho limitado | Grande capacidade |
| Limpeza automática | É necessária limpeza manual |
| Objetos de tamanho fixo | Objetos de tamanho dinâmico |
Use alocação na pilha para objetos pequenos e de curta duração. Use alocação no heap quando os objetos precisarem sobreviver ao escopo ou quando seu tamanho for determinado em tempo de execução.
Esquecer de excluir a memória da heap causa vazamentos de memória, uma fonte comum de bugs em programas C++.
Desafio
FácilVamos explorar a diferença entre a memória de pilha e a memória heap construindo uma classe simples Counter que acompanha como os objetos são criados e destruídos.
Você criará dois arquivos para organizar seu código:
Counter.h: Defina uma classeCountercom um atributo privadoname(string). Inclua um construtor que recebe um nome e exibe"Creating: <name>", e um destrutor que exibe"Destroying: <name>". Adicione um métodogetName()para retornar o nome do contador.main.cpp: Demonstre a alocação tanto na pilha quanto no heap. Leia um nome da entrada e, em seguida:- Crie um
Counteralocado na pilha usando esse nome - Crie um
Counteralocado no heap com o nome"HeapCounter" - Exiba os dois nomes dos contadores no formato
"Stack: <name>"e"Heap: <name>" - Exclua o contador alocado no heap para evitar um vazamento de memória
- Crie um
Observe como as mensagens do construtor e do destrutor aparecem em ordens diferentes, dependendo de quando você cria e exclui cada objeto. O objeto na pilha será destruído automaticamente quando main() terminar, enquanto o objeto no heap precisa ser excluído explicitamente.
Inclua seu arquivo de cabeçalho em main.cpp usando #include "Counter.h".
Experimente você mesmo
#include <iostream>
#include <string>
#include "Counter.h"
using namespace std;
int main() {
// Leia o nome da entrada
string inputName;
cin >> inputName;
// TODO: Crie um Counter alocado na stack usando inputName
// TODO: Crie um Counter alocado na heap com o nome "HeapCounter"
// TODO: Print stack counter name in format "Stack: <name>"
// TODO: Imprima o nome do contador da heap no formato "Heap: <name>"
// TODO: Delete o contador alocado na heap para evitar vazamento de memória
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online