sistemas resueltos para paginada paginacion operativos memoria gestion estatica espacios ejercicios ejemplos dinamica asignacion arreglos c++ memory-management

c++ - resueltos - memoria dinamica



¿Por qué la asignación de memoria de 2 ^ 80 bytes no falla? (5)

El siguiente código no lanza la excepción e imprime "éxito". Por qué ?

#include <iostream> int main() { size_t size = size_t(1024)*1024*1024*1024*1024*1024*1024*1024; char* data = new char[size]; if (data == NULL) std::cout << "fail" << std::endl; else std::cout << "success" << std::endl; return 0; }

  • Compilador: g ++ (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3
  • SO: Ubuntu 12.04
  • RAM: 8 GB

Y si así es como debe funcionar, ¿cómo verifico que tengo suficiente memoria?

[ Editar: hice mi código estúpido un poco más correcto, ahora al menos fallaría en x64 si elimino dos *1024 ]


Es más que probable que sea el hecho de que el número que está solicitando es demasiado grande para ser almacenado dentro de un número entero y está experimentando un desbordamiento aquí y la memoria asignada es, de hecho, mucho menos de lo que cree.

Aquí 2 ^ 80 = 1208925819614629174706176 de acuerdo con http://en.wikipedia.org/wiki/Yobibyte


Mi compilador puede responder a esta:

$ g++ --version g++ (GCC) 4.7.1 20120721 (prerelease) Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ -Wall -Wextra -pedantic q12507456.c++ q12507456.c++: In function ''int main()'': q12507456.c++:5:42: warning: integer overflow in expression [-Woverflow] $


Quizás esté al tanto de lo siguiente, pero lo expondré solo para aclararlo. Una excepción no se está lanzando literalmente, el código está siendo probado por las declaraciones if. Independientemente de la terminología y los métodos que esté utilizando para su prueba, hay una observación más relevante para tomar nota. Su sistema tiene un valor máximo para los enteros, y C ++ lo tendrá en cuenta durante la compilación haciendo verificaciones y comportándose de alguna manera en consecuencia. Una vez más, usted también puede saber eso. Mi conjetura sería que el valor volvió a 0 y luego a la cantidad excesiva o que el valor que estaba allí antes de que el puntero comenzara a señalarlo se mantuvo intacto (lo más probable). En ese caso, el puntero no sería NULL . Intente asignarlo a NULL después de la declaración, luego asigne la memoria y vea si el tiempo pasa sus declaraciones if.


Tenga en cuenta que en linux malloc (que en última instancia respalda lo new ) puede overcommit :

Desde la versión 2.1.27 hay un sysctl VM_OVERCOMMIT_MEMORY y proc file / proc / sys / vm / overcommit_memory con valores 1: overcommit y 0 (predeterminado): no.

malloc tendrá éxito y reservará el VA pero no lo respaldará con páginas. Cuando se accede a una página, puede o no tener éxito para cometerla. OOM Killer puede correr. Si todo falla, obtendrás un GPF en el acceso.

Las opiniones están divididas si este comportamiento es una locura (hay personas sanas en este campamento) o brillantes (las personas locas están en ese campamento).


1024*1024*1024*1024*1024*1024*1024*1024

provoca un desbordamiento de enteros cuando se calcula, es decir, se tomará módulo 2 ^ 32 (o 2 ^ 64, dependiendo de su sistema), y eso es cero bytes que pueden asignarse.