Usar malloc vs new asignadores en C++
-
Usar el operador
new
para asignar la memoria dinámica en C++ -
Usa el operador
new
ystd::unique_ptr
para asignar la memoria dinámica en C++ -
Usa la función
malloc
yrealloc
/reallocarray
para asignar la memoria dinámica
Este artículo explicará varios métodos de uso de los asignadores de malloc
vs. new
en C++.
Usar el operador new
para asignar la memoria dinámica en C++
new
es la interfaz preferida para manejar la memoria dinámica en C++ directamente. Construye un objeto del tipo dado y le devuelve el puntero. Los objetos asignados usando el operador new
son inicializados por defecto, lo que significa que los objetos de tipo incorporado y compuesto tienen valores basura que necesitan ser inicializados antes de ser usados.
Note que new
puede ser llamado con múltiples notaciones para satisfacer diferentes necesidades, pero en el siguiente ejemplo, asignamos el array int
de tamaño 10
. Así, el puntero devuelto almacenado en la variable arr1
apunta al trozo de memoria que es de 40
bytes. La función initPrintIntVector
sólo se implementa para demostrar mejor un ejemplo práctico de codificación. Ya que estamos usando el llamado puntero desnudo, es importante liberar la memoria asignada con el operador delete
antes de que el programa salga. Sin embargo, los corchetes después del delete
también son necesarios para distribuir cada posición en el array.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
int *arr1 = new int[SIZE];
initPrintIntVector(arr1, SIZE);
delete[] arr1;
return EXIT_SUCCESS;
}
Resultado (*aleatorio):
8; 380; 519; 536; 408; 666; 382; 244; 448; 165;
Usa el operador new
y std::unique_ptr
para asignar la memoria dinámica en C++
Aunque el new
operador parece ser una buena herramienta para la asignación dinámica de la memoria, puede ser bastante propenso a errores en las grandes bases de código con manipulaciones intensivas de la memoria. A saber, la asignación de los recursos de memoria en el momento adecuado es un problema bastante difícil de abordar, y en su mayoría resulta en fugas de memoria o errores de ejecución inesperados. Por eso la biblioteca estándar, desde la versión C++ 11 añadió punteros inteligentes que borran automáticamente la memoria a la que apuntan. std::unique_ptr
es un tipo de puntero inteligente, que sólo se permite a sí mismo apuntar al objeto dado. Nótese que la asignación se sigue haciendo usando el operador new
, y después de que el puntero haya sido usado podemos salir del programa sin llamar a delete
.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
std::unique_ptr<int[]> arr2(new int[SIZE]);
initPrintIntVector(arr2.get(), SIZE);
return EXIT_SUCCESS;
}
Producción :
985; 885; 622; 899; 616; 882; 117; 121; 354; 918;
Usa la función malloc
y realloc
/reallocarray
para asignar la memoria dinámica
Por otro lado, el código C++ puede llamar a la función asignadora original de estilo C - malloc
, que es una forma bastante arcaica de manipulación de la memoria dinámica para los estándares modernos de C++. No es la forma recomendada de asignar objetos en el montón, pero en el lado positivo, malloc
proporciona una funcionalidad más flexible.
Se llama a malloc
con un solo argumento que especifica el sizeof
del objeto y devuelve el void*
que debe ser lanzado al tipo correspondiente en C++. La única ventaja de la memoria asignada a malloc
es que puede ser expandida/contraída por la función realloc
o reallocarray
. La función realloc
toma el puntero al objeto y el nuevo tamaño como argumentos, mientras que reallocarray
toma el puntero, el número de elementos y el tamaño de cada elemento. Observe que si la memoria del objeto se expande, los antiguos valores almacenados permanecen intactos, y los elementos recién añadidos no se inicializan. Por lo tanto, el siguiente ejemplo imprime los elementos arr3
expandidos sólo con fines de demostración, y no debería ser el caso en el programa del mundo real.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
void printIntVector(int *arr, const int &size) {
for (int i = 0; i < size; ++i) {
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
int *arr3 = static_cast<int *>(malloc(SIZE * sizeof(int)));
// int *arr3 = static_cast<int *>(malloc(SIZE * sizeof *arr3));
// int *arr3 = static_cast<int *>(malloc(sizeof(int[SIZE])));
initPrintIntVector(arr3, SIZE);
arr3 = static_cast<int *>(reallocarray(arr3, NEW_SIZE, sizeof(int)));
// arr3 = static_cast<int *>(realloc(arr3, NEW_SIZE * sizeof(int)));
printIntVector(arr3, NEW_SIZE);
free(arr3);
return EXIT_SUCCESS;
}
Producción :
128; 346; 823; 134; 523; 487; 370; 584; 730; 268;
128; 346; 823; 134; 523; 487; 370; 584; 730; 268; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook