//Here is the original source code describing the problem: #include <cstdio> #include <new> using namespace std;
struct Simple { static void* operator new[](std::size_t, const std::nothrow_t&) throw() { return 0; } static void operator delete[](void* p, std::size_t) throw() {} // ^^^^^^^^^^^ if this is removed, the problem goes away int data; }; int main() { Simple* ps = new(nothrow) Simple[400000000]; printf("ps = %p\n", ps); if(ps) printf("pointer was not null (incorrect)\n"); else printf("pointer was null (correct)\n"); return 0; } /* Expected output: ps = 00000000 pointer was null (correct) Actual output: ps = 00000004 pointer was not null (incorrect) If I remove the std::size_t parameter from operator delete[], the problem goes away */ ////////////////////////////////////// gcc version 3.3.1 (mingw special 20030804-1) running on windows xp professional service pack 2 configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as -- host=mingw32 --target=mingw32 --prefix=mingw --enable-threads --disable-nls -- enable-languages=c,c++,f77,objc,ada,java --disable-win32-registry --disable- shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without- x --enable-java-cg=boehm --disable-libgcj-debug --enable-interpreter --enable- hash-synchronization Thread model: win32 ///////////////////////////////////// compiled with options: -W -Wall -ansi -pedantic -save-temps (as a console-application c++ project using Dev-C++ 4.9.9.1) compile log: Compiler: Default compiler Building Makefile: "C:\Dev-Cpp\projects\memchecker\Makefile.win" Executing make clean rm -f main.o memchecker.exe g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/include/c++" -I"C:/Dev- Cpp/include/c++/mingw32" -I"C:/Dev-Cpp/include/c++/backward" -I"C:/Dev- Cpp/include" -W -Wall -ansi -pedantic -save-temps g++.exe main.o -o "memchecker.exe" -L"C:/Dev-Cpp/lib" Execution terminated Compilation successful preprocessed main.ii: # 1 "main.cpp" # 1 "<built-in>" # 1 "<command line>" # 1 "main.cpp" # 1 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 1 3 # 48 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 3 # 1 "C:/Dev-Cpp/include/c++/3.3.1/mingw32/bits/c++config.h" 1 3 # 35 "C:/Dev-Cpp/include/c++/3.3.1/mingw32/bits/c++config.h" 3 # 1 "C:/Dev-Cpp/include/c++/3.3.1/mingw32/bits/os_defines.h" 1 3 # 36 "C:/Dev-Cpp/include/c++/3.3.1/mingw32/bits/c++config.h" 2 3 # 50 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 2 3 # 1 "C:/Dev-Cpp/include/c++/3.3.1/cstddef" 1 3 # 47 "C:/Dev-Cpp/include/c++/3.3.1/cstddef" 3 # 1 "C:/Dev-Cpp/include/stddef.h" 1 3 # 1 "C:/Dev-Cpp/include/stddef.h" 1 3 # 1 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stddef.h" 1 3 4 # 158 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stddef.h" 3 4 typedef int ptrdiff_t; # 220 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stddef.h" 3 4 typedef unsigned int size_t; # 7 "C:/Dev-Cpp/include/stddef.h" 2 3 # 7 "C:/Dev-Cpp/include/stddef.h" 2 3 # 49 "C:/Dev-Cpp/include/c++/3.3.1/cstddef" 2 3 namespace std { using ::ptrdiff_t; using ::size_t; } # 51 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 2 3 # 1 "C:/Dev-Cpp/include/stdio.h" 1 3 # 19 "C:/Dev-Cpp/include/stdio.h" 3 # 1 "C:/Dev-Cpp/include/_mingw.h" 1 3 # 20 "C:/Dev-Cpp/include/stdio.h" 2 3 # 1 "C:/Dev-Cpp/include/stddef.h" 1 3 # 1 "C:/Dev-Cpp/include/stddef.h" 1 3 # 1 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stddef.h" 1 3 4 # 361 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stddef.h" 3 4 typedef short unsigned int wint_t; # 7 "C:/Dev-Cpp/include/stddef.h" 2 3 # 7 "C:/Dev-Cpp/include/stddef.h" 2 3 # 27 "C:/Dev-Cpp/include/stdio.h" 2 3 # 1 "C:/Dev-Cpp/include/stdarg.h" 1 3 # 1 "C:/Dev-Cpp/include/stdarg.h" 1 3 # 1 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stdarg.h" 1 3 4 # 44 "C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include/stdarg.h" 3 4 typedef __builtin_va_list __gnuc_va_list; # 7 "C:/Dev-Cpp/include/stdarg.h" 2 3 # 7 "C:/Dev-Cpp/include/stdarg.h" 2 3 # 29 "C:/Dev-Cpp/include/stdio.h" 2 3 # 135 "C:/Dev-Cpp/include/stdio.h" 3 typedef struct _iobuf { char* _ptr; int _cnt; char* _base; int _flag; int _file; int _charbuf; int _bufsiz; char* _tmpfname; } FILE; # 160 "C:/Dev-Cpp/include/stdio.h" 3 extern __attribute__ ((dllimport)) FILE _iob[]; # 169 "C:/Dev-Cpp/include/stdio.h" 3 extern "C" { FILE* __attribute__((__cdecl__)) fopen (const char*, const char*); FILE* __attribute__((__cdecl__)) freopen (const char*, const char*, FILE*); int __attribute__((__cdecl__)) fflush (FILE*); int __attribute__((__cdecl__)) fclose (FILE*); int __attribute__((__cdecl__)) remove (const char*); int __attribute__((__cdecl__)) rename (const char*, const char*); FILE* __attribute__((__cdecl__)) tmpfile (void); char* __attribute__((__cdecl__)) tmpnam (char*); # 195 "C:/Dev-Cpp/include/stdio.h" 3 int __attribute__((__cdecl__)) setvbuf (FILE*, char*, int, size_t); void __attribute__((__cdecl__)) setbuf (FILE*, char*); int __attribute__((__cdecl__)) fprintf (FILE*, const char*, ...); int __attribute__((__cdecl__)) printf (const char*, ...); int __attribute__((__cdecl__)) sprintf (char*, const char*, ...); int __attribute__((__cdecl__)) _snprintf (char*, size_t, const char*, ...); int __attribute__((__cdecl__)) vfprintf (FILE*, const char*, __gnuc_va_list); int __attribute__((__cdecl__)) vprintf (const char*, __gnuc_va_list); int __attribute__((__cdecl__)) vsprintf (char*, const char*, __gnuc_va_list); int __attribute__((__cdecl__)) _vsnprintf (char*, size_t, const char*, __gnuc_va_list); int __attribute__((__cdecl__)) snprintf(char* s, size_t n, const char* format, ...); inline int __attribute__((__cdecl__)) vsnprintf (char* s, size_t n, const char* format, __gnuc_va_list arg) { return _vsnprintf ( s, n, format, arg); } int __attribute__((__cdecl__)) vscanf (const char * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) vfscanf (FILE * __restrict__, const char * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) vsscanf (const char * __restrict__, const char * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) fscanf (FILE*, const char*, ...); int __attribute__((__cdecl__)) scanf (const char*, ...); int __attribute__((__cdecl__)) sscanf (const char*, const char*, ...); int __attribute__((__cdecl__)) fgetc (FILE*); char* __attribute__((__cdecl__)) fgets (char*, int, FILE*); int __attribute__((__cdecl__)) fputc (int, FILE*); int __attribute__((__cdecl__)) fputs (const char*, FILE*); char* __attribute__((__cdecl__)) gets (char*); int __attribute__((__cdecl__)) puts (const char*); int __attribute__((__cdecl__)) ungetc (int, FILE*); int __attribute__((__cdecl__)) _filbuf (FILE*); int __attribute__((__cdecl__)) _flsbuf (int, FILE*); inline int __attribute__((__cdecl__)) getc (FILE* __F) { return (--__F->_cnt >= 0) ? (int) (unsigned char) *__F->_ptr++ : _filbuf (__F); } inline int __attribute__((__cdecl__)) putc (int __c, FILE* __F) { return (--__F->_cnt >= 0) ? (int) (unsigned char) (*__F->_ptr++ = (char)__c) : _flsbuf (__c, __F); } inline int __attribute__((__cdecl__)) getchar (void) { return (--(&_iob[0])->_cnt >= 0) ? (int) (unsigned char) *(&_iob[0])->_ptr++ : _filbuf ((&_iob[0])); } inline int __attribute__((__cdecl__)) putchar(int __c) { return (--(&_iob[1])->_cnt >= 0) ? (int) (unsigned char) (*(&_iob[1])->_ptr++ = (char)__c) : _flsbuf (__c, (&_iob[1]));} # 294 "C:/Dev-Cpp/include/stdio.h" 3 size_t __attribute__((__cdecl__)) fread (void*, size_t, size_t, FILE*); size_t __attribute__((__cdecl__)) fwrite (const void*, size_t, size_t, FILE*); int __attribute__((__cdecl__)) fseek (FILE*, long, int); long __attribute__((__cdecl__)) ftell (FILE*); void __attribute__((__cdecl__)) rewind (FILE*); # 327 "C:/Dev-Cpp/include/stdio.h" 3 typedef long long fpos_t; int __attribute__((__cdecl__)) fgetpos (FILE*, fpos_t*); int __attribute__((__cdecl__)) fsetpos (FILE*, const fpos_t*); int __attribute__((__cdecl__)) feof (FILE*); int __attribute__((__cdecl__)) ferror (FILE*); inline int __attribute__((__cdecl__)) feof (FILE* __F) { return __F->_flag & 0x0010; } inline int __attribute__((__cdecl__)) ferror (FILE* __F) { return __F->_flag & 0x0020; } void __attribute__((__cdecl__)) clearerr (FILE*); void __attribute__((__cdecl__)) perror (const char*); # 425 "C:/Dev-Cpp/include/stdio.h" 3 int __attribute__((__cdecl__)) fwprintf (FILE*, const wchar_t*, ...); int __attribute__((__cdecl__)) wprintf (const wchar_t*, ...); int __attribute__((__cdecl__)) swprintf (wchar_t*, const wchar_t*, ...); int __attribute__((__cdecl__)) _snwprintf (wchar_t*, size_t, const wchar_t*, ...); int __attribute__((__cdecl__)) vfwprintf (FILE*, const wchar_t*, __gnuc_va_list); int __attribute__((__cdecl__)) vwprintf (const wchar_t*, __gnuc_va_list); int __attribute__((__cdecl__)) vswprintf (wchar_t*, const wchar_t*, __gnuc_va_list); int __attribute__((__cdecl__)) _vsnwprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list); int __attribute__((__cdecl__)) fwscanf (FILE*, const wchar_t*, ...); int __attribute__((__cdecl__)) wscanf (const wchar_t*, ...); int __attribute__((__cdecl__)) swscanf (const wchar_t*, const wchar_t*, ...); wint_t __attribute__((__cdecl__)) fgetwc (FILE*); wint_t __attribute__((__cdecl__)) fputwc (wchar_t, FILE*); wint_t __attribute__((__cdecl__)) ungetwc (wchar_t, FILE*); wchar_t* __attribute__((__cdecl__)) fgetws (wchar_t*, int, FILE*); int __attribute__((__cdecl__)) fputws (const wchar_t*, FILE*); wint_t __attribute__((__cdecl__)) getwc (FILE*); wint_t __attribute__((__cdecl__)) getwchar (void); wchar_t* __attribute__((__cdecl__)) _getws (wchar_t*); wint_t __attribute__((__cdecl__)) putwc (wint_t, FILE*); int __attribute__((__cdecl__)) _putws (const wchar_t*); wint_t __attribute__((__cdecl__)) putwchar (wint_t); FILE* __attribute__((__cdecl__)) _wfdopen(int, wchar_t *); FILE* __attribute__((__cdecl__)) _wfopen (const wchar_t*, const wchar_t*); FILE* __attribute__((__cdecl__)) _wfreopen (const wchar_t*, const wchar_t*, FILE*); FILE* __attribute__((__cdecl__)) _wfsopen (const wchar_t*, const wchar_t*, int); wchar_t* __attribute__((__cdecl__)) _wtmpnam (wchar_t*); wchar_t* __attribute__((__cdecl__)) _wtempnam (const wchar_t*, const wchar_t*); int __attribute__((__cdecl__)) _wrename (const wchar_t*, const wchar_t*); int __attribute__((__cdecl__)) _wremove (const wchar_t*); void __attribute__((__cdecl__)) _wperror (const wchar_t*); FILE* __attribute__((__cdecl__)) _wpopen (const wchar_t*, const wchar_t*); int __attribute__((__cdecl__)) snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); inline int __attribute__((__cdecl__)) vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __gnuc_va_list arg) { return _vsnwprintf ( s, n, format, arg);} int __attribute__((__cdecl__)) vwscanf (const wchar_t * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) vfwscanf (FILE * __restrict__, const wchar_t * __restrict__, __gnuc_va_list); int __attribute__((__cdecl__)) vswscanf (const wchar_t * __restrict__, const wchar_t * __restrict__, __gnuc_va_list); # 501 "C:/Dev-Cpp/include/stdio.h" 3 } # 53 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 2 3 # 97 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 3 namespace std { using ::FILE; using ::fpos_t; using ::clearerr; using ::fclose; using ::feof; using ::ferror; using ::fflush; using ::fgetc; using ::fgetpos; using ::fgets; using ::fopen; using ::fprintf; using ::fputc; using ::fputs; using ::fread; using ::freopen; using ::fscanf; using ::fseek; using ::fsetpos; using ::ftell; using ::fwrite; using ::getc; using ::getchar; using ::gets; using ::perror; using ::printf; using ::putc; using ::putchar; using ::puts; using ::remove; using ::rename; using ::rewind; using ::scanf; using ::setbuf; using ::setvbuf; using ::sprintf; using ::sscanf; using ::tmpfile; using ::tmpnam; using ::ungetc; using ::vfprintf; using ::vprintf; using ::vsprintf; } # 153 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 3 namespace __gnu_cxx { # 167 "C:/Dev-Cpp/include/c++/3.3.1/cstdio" 3 using ::snprintf; using ::vfscanf; using ::vscanf; using ::vsnprintf; using ::vsscanf; } namespace std { using __gnu_cxx::snprintf; using __gnu_cxx::vfscanf; using __gnu_cxx::vscanf; using __gnu_cxx::vsnprintf; using __gnu_cxx::vsscanf; } # 2 "main.cpp" 2 # 1 "C:/Dev-Cpp/include/c++/3.3.1/new" 1 3 # 42 "C:/Dev-Cpp/include/c++/3.3.1/new" 3 # 1 "C:/Dev-Cpp/include/c++/3.3.1/exception" 1 3 # 40 "C:/Dev-Cpp/include/c++/3.3.1/exception" 3 extern "C++" { namespace std { # 52 "C:/Dev-Cpp/include/c++/3.3.1/exception" 3 class exception { public: exception() throw() { } virtual ~exception() throw(); virtual const char* what() const throw(); }; class bad_exception : public exception { public: bad_exception() throw() { } virtual ~bad_exception() throw(); }; typedef void (*terminate_handler) (); typedef void (*unexpected_handler) (); terminate_handler set_terminate(terminate_handler) throw(); void terminate() __attribute__ ((__noreturn__)); unexpected_handler set_unexpected(unexpected_handler) throw(); void unexpected() __attribute__ ((__noreturn__)); # 100 "C:/Dev-Cpp/include/c++/3.3.1/exception" 3 bool uncaught_exception() throw(); } namespace __gnu_cxx { # 113 "C:/Dev-Cpp/include/c++/3.3.1/exception" 3 void __verbose_terminate_handler (); } } # 43 "C:/Dev-Cpp/include/c++/3.3.1/new" 2 3 extern "C++" { namespace std { class bad_alloc : public exception { public: bad_alloc() throw() { } virtual ~bad_alloc() throw(); }; struct nothrow_t { }; extern const nothrow_t nothrow; typedef void (*new_handler)(); new_handler set_new_handler(new_handler) throw(); } # 82 "C:/Dev-Cpp/include/c++/3.3.1/new" 3 void* operator new(std::size_t) throw (std::bad_alloc); void* operator new[](std::size_t) throw (std::bad_alloc); void operator delete(void*) throw(); void operator delete[](void*) throw(); void* operator new(std::size_t, const std::nothrow_t&) throw(); void* operator new[](std::size_t, const std::nothrow_t&) throw(); void operator delete(void*, const std::nothrow_t&) throw(); void operator delete[](void*, const std::nothrow_t&) throw(); inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void* operator new[](std::size_t, void* __p) throw() { return __p; } inline void operator delete (void*, void*) throw() { }; inline void operator delete[](void*, void*) throw() { }; } # 3 "main.cpp" 2 using namespace std; struct Simple { static void* operator new[](std::size_t, const std::nothrow_t&) throw() { return 0; } static void operator delete[](void* p, std::size_t) throw() {} int data; }; int main() { Simple* ps = new(nothrow) Simple[400000000]; printf("ps = %p\n", ps); if(ps) printf("pointer was not null (incorrect)\n"); else printf("pointer was null (correct)\n"); return 0; } -- Summary: class-specific nothrow array new and delete not returning null Product: gcc Version: 3.3.1 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mkunka2 at earthlink dot net CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19975