Ver Mensaje Individual
  #3 (permalink)  
Antiguo 13/03/2015, 15:02
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Respuesta inesperada en asignación de memoria

Cita:
Iniciado por cristiansc93 Ver Mensaje
Código C++:
Ver original
  1. // Utilizo zero por que no me gusta modificar el compilador para que
  2. //agarren los null y nullptr
modificar el compilador?? nullptr es una palabra reservada de c++... lo que pasa es que solo está disponible a partir del estándar del 2011 (el anterior data de 1999).

null, en cambio, suele ser una convención. No es más que un alias de 0.

Personalmente creo más beneficioso usar nullptr, null y 0 (en ese estricto orden) para inicializar punteros. ¿Mis motivos? explicados en el siguiente ejemplo: Imagina que te encuentras las 3 asignaciones siguientes entre medias del código... que conclusión puedes sacar de cada una, sin conocer el resto del codigo?

Código C++:
Ver original
  1. var = 0; // Puede ser un puntero... o un número!!!
  2. var = NULL; // Entiendo que debería ser un puntero, pero también se puede usar en variables numéricas
  3. var = nullptr; // Esta asignación únicamente funciona con punteros

Queda claro, por tanto, que si ves un nullptr es que esa variable se trata de un puntero.

Otra ventaja de nullptr la encuentras en el caso de funciones sobrecargadas:

Código C++:
Ver original
  1. void func( int )
  2. {
  3.   std::cout << "func(int)" << std::endl;
  4. }
  5.  
  6. void func( char* )
  7. {
  8.   std::cout << "func(char*)" << std::endl;
  9. }
  10.  
  11. int main( )
  12. {
  13.   func( 0 ); // func(int)
  14.   func( NULL ); // func( int )
  15.   func( nullptr ); // func(char*)
  16. }

Si con esto no te he convencido, no se me ocurre que más puedo hacer :)


Código C++:
Ver original
  1. long long int n = 0;
  2. // ...
  3. p= new (nothrow) long long int[n];

Ojo con esto!!! La primera reserva que intentas hacer no es válida. No puedes crear un array de 0 elementos. El mínimo es 1.

Y, para rematar. Dices que el programa finaliza con 30.000. Veamos:

* Utilizas long long int, es decir, supongamos 64 bits
* 30.000 * 64 = 1.920.000 bits = 1.875 kb = 1.83 Mb

Es poca memoria... si, pero fíjate que dentro del bucle no liberas memoria... lo haces al salir del bucle. Pero claro, sales del bucle cuando ha fallado la reserva de memoria, luego p vale 0, luego ese delete no hace absolutamente nada.

Por otro lado, dado que no liberas memoria, el programa va creciendo y creciendo.

Un cálculo rápido nos dice que ( 30.000 * 64 ) * 15.000 = 28.800.000.000 bits consumidos = 28.125.000 kb = 27.465 Mb = 26.82 Gb.

Este cálculo es aproximado y te dice (si no me he confundido con las cuentas) la memoria consumida en 30.000 ciclos.

Como puedes ver, no es moco de pavo.

Un saludo.