Pongo mi explicación en el código:
Código C++:
Ver original#include <iostream>
#include <new>
#include <limits>
#include <cstdint>
int main()
{
long long n = std::numeric_limits<long long>::max();
long long *p;
int nCeros=0;
do{
p= new (std::nothrow) long long[n];
if (p == nullptr){
nCeros++;
n = std::numeric_limits<long long>::max() / (10 * nCeros);
}
} while (p == nullptr);
long long bytes = n * sizeof(long long);
std::cout << "\nDa la impresion de que se hubiera podido obtener memoria para "
<< bytes << " Bytes;\n";
std::cout << "(Que serian " << bytes/1024.0/1024/1024 << " GB)\n\n";
std::cout << "Incluso se puede tener la ilusion de que es posible\n"
"operar sobre ese espacio de memoria ...\n\n";
std::cout << "Por ejemplo:\n";
p[0] = 5;
p[n-1] = 6;
std::cout << "p[0] = " << p[0] << '\n';
std::cout << "p[" << n-1 << "] = " << p[n-1] << '\n';
std::cout << "\nPero, realmente? Existe algo que se llame p[" << n-1 << "]?\n\n";
std::cout << "size_t desilucion;\n";
size_t desilusion;
std::cout << "El operator new usa el tipo size_t para el tamaño de los objetos.\n\n";
std::cout << "En este caso, haciendo desilusion = n-1:\n";
desilusion = n-1; // el compilador debería advertir que se trunca
std::cout << "la asignacion parece decir: desilusion = " << n-1 << ";\n\n"
"pero en realidad, al truncarse, lo que realmente queda es:\n";
std::cout << "desilusion == " << desilusion << "\n\n";
std::cout << "De modo que:\n";
std::cout << "p[0] == " << p[0] << '\n';
std::cout << "p[" << desilusion << "] == " << p[desilusion] << "\n\n";
std::cout << "Como puede verse, el tamaño efectivamente asignado fue de:\n";
std::cout << desilusion * sizeof(long long) << " Bytes;\n";
std::cout << "que son " << desilusion * sizeof(long long)/ 1024.0/1024/1024
<< " GB,\nque ya no es tan burrada, o es una burrada dentro de los limites esperados.\n\n";
std::cout << "P.D.: Aunque los arrays no son punteros... (es broma :),\n"
"siempre que se trate de direcciones de memoria, la medida\n"
"deberia expresarse en size_t\n";
}