once upon a time |calloc(BIG,BIG)| silently overflowed, now it is fixed. nowadays |new int[bignumber]| overflows as in: [1] volatile size_t n; n= 4+((size_t)-1)/sizeof(int); int *ptr; cout << "n=" << n << endl; ptr=new int[n]; cout << "ptr=" << ptr << endl; cout << "ptr[n/2]=" << ptr[n/2] << endl; ./a.out n=4611686018427387907 ptr=0x602010 Segmentation fault
[2] |int| may be replaced by another |Class|. ironically, fixing with checking for overflow of sizeof(Class)*numclasses is not enough because g++ adds |epsilon| >= sizeof(size_t) probably to know how many |this| to destruct later. #define TYP CL n= ((size_t)-1)/sizeof(TYP); TYP *ptr; cout << "size=" << sizeof(CL) <<endl; cout << "n=" << n << " (size_t) (n * sizeof(Class))="<< (size_t) (n*sizeof(CL)) << endl; ptr=new TYP[n]; cout << "ptr=" << ptr << endl; ./a.out size=4 n=4611686018427387903 (size_t) (n * sizeof(Class))=18446744073709551612 Segmentation fault another oddity is a class that has no properties, just methods, has sizeof(Class) == 1 ( i naiively expected 0) and it is possible to |new []| *a lot of them* with completely invalid |this| without crashing, though such cases are probably not very realistic. testcases new1.cc and new2.cc attached.
using namespace std; #include <iostream> int main() { volatile size_t n; n= 4+((size_t)-1)/sizeof(int); int *ptr; cout << "n=" << n << endl; ptr=new int[n]; cout << "ptr=" << ptr << endl; cout << "ptr[n/2]=" << ptr[n/2] << endl; return 4; }
using namespace std; #include <iostream> class CL { public: int a; CL() { //cout << "construct CL" << endl; a=3; } ~CL() {cout << "d " << this << endl;} }; int main() { volatile size_t n; #define TYP CL n= ((size_t)-1)/sizeof(TYP); TYP *ptr; cout << "size=" << sizeof(CL) <<endl; cout << "n=" << n << " (size_t) (n * sizeof(Class))="<< (size_t) (n*sizeof(CL)) << endl; ptr=new TYP[n]; cout << "ptr=" << ptr << endl; delete [] ptr; return 4; }