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;
}