Román, miembro de este gran equipo de trabajo, nos ha hecho el favor de escribir este escrito porque domina perfectamente este tema.
Solución:
probablemente sea true que C++ new
es más seguro que malloc()
pero eso no hace automáticamente malloc()
más inseguro de lo que era antes. ¿Tu amigo dijo por qué lo considera inseguro?
Sin embargo, aquí hay algunas cosas a las que debe prestar atención:
1) Con C++, debe tener cuidado cuando utilizar malloc()
/free()
y new
/delete
lado a lado en el mismo programa. Esto es posible y permisible, pero todo lo que fue asignado con malloc()
debe ser liberado con free()
y no con delete
. Del mismo modo, todo lo que se asignó con new
debe ser liberado con delete
y nunca con free()
. (Esta lógica va aún más lejos: si asigna un array con new[]
debes liberarlo con delete[]
y no solo con delete
.) Utilice siempre las contrapartes correspondientes para asignación y desasignación, por objeto.
int* ni = new int;
free(ni); // ERROR: don't do this!
delete ni; // OK
int* mi = (int*)malloc(sizeof(int));
delete mi; // ERROR!
free(mi); // OK
2)malloc()
y new
(hablando de nuevo de C++) no hagas exactamente lo mismo. malloc()
solo te da una porción de memoria para usar; new
será además llamar a un constructor (si está disponible). Similar, delete
llamará a un destructor (si está disponible), mientras que free()
no lo haré Esto podría generar problemas, como objetos inicializados incorrectamente (porque no se llamó al constructor) o recursos no liberados (porque no se llamó al destructor).
3) C++ new
también se ocupa de asignar la cantidad correcta de memoria para el tipo especificado, mientras que usted necesita calcular esto usted mismo con malloc()
:
int *ni = new int;
int *mi = (int*)malloc(sizeof(int)); // required amount of memory must be
// explicitly specified!
// (in some situations, you can make this
// a little safer against code changes by
// writing sizeof(*mi) instead.)
Conclusión:
En C++, new
/delete
debe preferirse a malloc()
/free()
donde sea posible. (C ª, new
/delete
no está disponible, por lo que la elección sería obvia allí).
[…] C/C++ es un lenguaje inseguro bien conocido. […]
En realidad, eso está mal. En realidad, “C/C++” ni siquiera existe. hay Cy ahí está C++. Comparten algo (o, si quieres, mucha) sintaxis, pero de hecho son idiomas muy diferentes.
Una cosa en la que difieren enormemente es en su forma de gestionar la memoria dinámica. La forma C de hecho está usando malloc()
/free()
y si necesita memoria dinámica, hay muy poco que pueda hacer más que usarlos (o algunos hermanos de malloc()
).
La forma de C++ es no(a mano)tratar con recursos dinámicos (de los cuales la memoria es solo una) en absoluto. La administración de recursos se entrega a unas pocas clases bien implementadas y probadas, preferiblemente de la biblioteca estándar, y luego se realiza automáticamente. Por ejemplo, en lugar de tratar manualmente con búferes de caracteres terminados en cero, hay std::string
en lugar de tratar manualmente con arreglos asignados dinámicamente, hay std:vector
en lugar de tratar manualmente con archivos abiertos, está el std::fstream
familia de arroyos, etc.
Tu amigo podría estar hablando de:
-
La seguridad del uso de punteros en general. Por ejemplo, en C++ si está asignando un array de char con malloc, pregunta por qué no estás usando un
string
ovector
. Los punteros no son inseguros, pero el código que tiene errores debido al uso incorrecto de los punteros sí lo es. -
Algo sobre malloc en particular. La mayoría de los sistemas operativos borran la memoria antes de entregarla por primera vez a un proceso, por razones de seguridad. De lo contrario, los datos confidenciales de una aplicación podrían filtrarse a otra aplicación. En los sistemas operativos que no hacen eso, podría argumentar que hay una inseguridad relacionada con
malloc
. Realmente está más relacionado confree
.
También es posible que tu amigo no sepa de qué está hablando. Cuando alguien dice “X es inseguro”, mi respuesta es “¿de qué manera?”.