Menu

The new operator throws DJVU::GException

unitwest
2012-07-27
2012-11-08
  • unitwest

    unitwest - 2012-07-27

    I'm puzzled why the following code throws DJVU::GException instead of
    std::bad_alloc.

    #include <new>
    int main(void)
    {
        int *bar = new int[3000000000];
    
        return 0;
    }
    

    If I compile this with "g++ -o foo foo.cpp -ldjvulibre" and execute "./foo", I
    get:

    terminate called after throwing an instance of 'DJVU::GException'
    Aborted
    

    If I compile it with "g++ -o foo foo.cpp" and execute, then I get:

    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc
    Aborted
    

    Merely linking libdjvulibre changes the behaviour of the code above (which is
    independent of libdjvulibre). Can I somehow make libdjvulibre not bleed
    outside its API?

     
  • Dr Bill C Riemers

    DjVu Libre overloads new.

    Bill

     
  • unitwest

    unitwest - 2012-07-27

    Thanks, Bill. It appears to not actually overload, but modify the behaviour of
    the standard new. From GException.cpp:

    static void (*old_handler)() = std::set_new_handler(throw_memory_error);
    

    So if I compile and link the following with djvulibre, I get std::bad_alloc
    back:

    #include <new>
    int main(void)
    {
        std::set_new_handler(0);
        int *bar = new int[3000000000];
        return 0;
    }
    

    Of course, doing that likely breaks error handling inside djvulibre.

    IMO, djvulibre shouldn't make such a global modification. It seems
    DJVU::GException is not part of the API (ddjvuapi.h, miniexp.h). Also, what
    if another library I linked in did the same? Then one or the other would have
    broken error handling. I guess there's no easy way to fix this, though. So
    I'll just try not caring about mem alloc failures. :)

     

Log in to post a comment.