Operator new inicializa la memoria a cero

Hay tal código:

#include  int main(){ unsigned int* wsk2 = new unsigned int(5); std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; delete wsk2; wsk2 = new unsigned int; std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; return 0; } 

Resultado:

 wsk2: 0x928e008 5 wsk2: 0x928e008 0 

He leído que new no inicializa la memoria con ceros. Pero aquí parece que sí. ¿Como funciona?

Hay dos versiones:

 wsk = new unsigned int; // default initialized (ie nothing happens) wsk = new unsigned int(); // zero initialized (ie set to 0) 

También funciona para matrices:

 wsa = new unsigned int[5]; // default initialized (ie nothing happens) wsa = new unsigned int[5](); // zero initialized (ie all elements set to 0) 

En respuesta a comentar a continuación.

Ehm … ¿estás seguro de que la nueva int5 sin signo cerra los enteros?

Aparentemente sí:

[C ++ 11: 5.3.4 / 15]: una nueva expresión que crea un objeto de tipo T inicializa ese objeto de la siguiente manera: Si se omite el nuevo inicializador, el objeto se inicializa por defecto (8.5); si no se realiza la inicialización, el objeto tiene un valor indeterminado. De lo contrario, el nuevo inicializador se interpreta según las reglas de inicialización de 8.5 para la inicialización directa.

 #include  #include  int main() { unsigned int wsa[5] = {1,2,3,4,5}; // Use placement new (to use a know piece of memory). // In the way described above. // unsigned int* wsp = new (wsa) unsigned int[5](); std::cout << wsa[0] << "\n"; // If these are zero then it worked as described. std::cout << wsa[1] << "\n"; // If they contain the numbers 1 - 5 then it failed. std::cout << wsa[2] << "\n"; std::cout << wsa[3] << "\n"; std::cout << wsa[4] << "\n"; } 

Resultados:

 > g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.2.0 Thread model: posix > g++ t.cpp > ./a.out 0 0 0 0 0 > 

operator new no garantiza la inicialización de la memoria a nada, y la nueva expresión que asigna un unsigned int sin unsigned int sin un nuevo inicializador deja el objeto con un valor indeterminado.

Leer el valor de un objeto no inicializado da como resultado un comportamiento indefinido . El comportamiento indefinido incluye evaluar el valor cero sin efectos nocivos, pero podría dar lugar a que ocurra algo, por lo que debe evitar causarlo.

En C ++ 11, el lenguaje utilizado es que los objetos asignados se inicializan por defecto, lo que para los tipos que no son de clase significa que no se realiza ninguna inicialización. Esto es diferente del significado de default-initialized en C ++ 03.

Con algunos comstackdores, la versión de depuración de los nuevos inicializará los datos, pero ciertamente no hay nada en lo que pueda confiar.

También es posible que la memoria acabara de tener 0 de un uso anterior. No suponga que no pasó nada en la memoria entre eliminar y nuevo. Podría haber algo hecho en el fondo que nunca notaste. Además, el mismo valor de puntero podría no ser la misma memoria física. Las páginas de memoria se mueven y paginan hacia afuera y hacia adentro. Un puntero puede asignarse a una ubicación completamente diferente a la anterior.

En pocas palabras: si no inicializó específicamente una ubicación de memoria, entonces no puede asumir nada sobre su contenido. Es posible que el administrador de memoria ni siquiera asigne una ubicación de memoria física específica hasta que use la memoria.

La gestión moderna de la memoria es increíblemente compleja, pero como progtwigdor C ++ no te importa (sobre todo ‡). Juega según las reglas y no te meterás en problemas.

‡ Le puede importar si está optimizando para reducir las fallas de la página.

Eso no es operator new , ese es el new operador. ¡De hecho, hay una gran diferencia! La diferencia es que el operator new es una función que devuelve la memoria en bruto; cuando usa el new operador, invoca un constructor por usted. Es el constructor el que establece el valor de ese int , no operator new .