Memoria Stack vs Heap
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 12 de 104.
Los programas de C++ utilizan dos regiones principales de memoria: la pila y el heap. Comprender dónde viven tus objetos es fundamental para escribir código eficiente y sin errores.
La pila es memoria rápida y automática. Las variables declaradas dentro de las funciones viven aquí y se destruyen automáticamente cuando salen de ámbito.
void example() {
int x = 10; // Asignación en la pila
Player player; // Asignación en la pila - destruido automáticamente
} // x y player se destruyen aquíEl heap es una memory más grande pero más lenta que gestionas manualmente. Los objetos en el heap persisten hasta que los delete explícitamente.
void example() {
Player* player = new Player(); // Asignación en el heap
// player existe hasta que se elimine
delete player; // Se requiere limpieza manual
}Diferencias clave:
| Stack | Heap |
|---|---|
| Asignación rápida | Asignación más lenta |
| Tamaño limitado | Gran capacidad |
| Limpieza automática | Se necesita limpieza Manual |
| Objetos de tamaño fijo | Objetos de tamaño dinámico |
Usa asignación en la pila para objetos pequeños y de corta duración. Usa asignación en el montón cuando los objetos deban sobrevivir a su ámbito o cuando su tamaño se determine en tiempo de ejecución.
Olvidar eliminar la memoria del
Desafío
FácilExploremos la diferencia entre la memoria de la pila y la memoria del montón mediante la construcción de una clase simple Counter que realiza un seguimiento de cómo se crean y destruyen los objetos.
Crearás dos archivos para organizar tu código:
Counter.h: define una claseCountercon un atributonameprivate (string). Incluye un constructor que recibe un nombre e imprime"Creating: <name>", y un destructor que imprime"Destroying: <name>". Añade un métodogetName()para return el nombre del contador.main.cpp: demuestra la allocation tanto en la pila como en el montón. Read un nombre desde input, después:- Create un
Counterallocated en la pila usando ese nombre - Create un
Counterallocated en el montón con el nombre"HeapCounter" - Print ambos nombres de contador en el format
"Stack: <name>"y"Heap: <name>" - Delete el contador allocated en el montón para prevent un memory leak
- Create un
Observa cómo los mensajes del constructor y del destructor aparecen en distintos órdenes según cuándo crees y elimines cada objeto. El objeto de la pila se destruirá automatically cuando termine main(), mientras que el objeto del montón debe eliminarse explícitamente.
Include tu archivo de encabezado en main.cpp usando #include "Counter.h".
Pruébalo tú mismo
#include <iostream>
#include <string>
#include "Counter.h"
using namespace std;
int main() {
// Lee el nombre de la entrada
string inputName;
cin >> inputName;
// TODO: Crea un Counter asignado en la pila usando inputName
// TODO: Crea un Counter asignado en el montón con el nombre "HeapCounter"
// TODO: Print stack counter name in format "Stack: <name>"
// TODO: Imprime el nombre del contador del montón en el formato "Heap: <name>"
// TODO: Elimina el contador asignado en el montón para evitar una fuga de memoria
return 0;
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosConstrucción y compilación en C++Archivos de cabecera y archivos fuenteNamespaces y alcanceIntroducción a OOP en C++Clases vs ObjetosEl puntero 'this'Métodos (Funciones miembro)Atributos (Miembros de datos)Conceptos básicos de Ctors y DtorsResumen - Calculadora simple4Propiedades de clase
Miembros de instancia vs. estáticosGetters y SettersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases amigasResumen - Gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de Ctor y DtorSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualResumen - Jerarquía de empleados2Gestión de memoria
Memoria Stack vs HeapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Resumen - Gestor de arrays dinámicos5Encapsulamiento
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultamiento de informaciónStruct vs ClassClases anidadas e internasResumen - Sistema de registros de estudiantes8Polimorfismo
Polimorfismo: Compilación vs. Tiempo de ejecuciónSobrecarga de funcionesFunciones virtuales revisadasFunciones virtuales purasClases abstractasDiseño de interfaces en C++Dynamic Casting y RTTIResumen: Calculadora de figuras11Conceptos avanzados de POO
Composición vs. HerenciaMixins mediante CRTPIdioma PimplBorrado de tiposEnum Classes y tipado fuerteManejo de excepciones en POOJerarquías de excepciones personalizadas14Patrones de diseño - Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositeRAII como patrón3Constructores y Destructores
Constructor por defectoConstructor parametrizadoConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis profundo del destructorRegla de tres / cinco / ceroResumen - Clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujo (Stream)Sobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tiposResumen - Clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasConceptos básicos de SFINAE y Type TraitsResumen - Contenedor genéricoPractica por tu cuenta: Compilador de C++ online