5

try satırındaki new ifadesi, bilgisayarımda bir bad_alloc istisnası atar.Neden "e.what()", "kötü ayırma" yazdırır?

Yakalama maddesinin, başvuruyla değil, değer olarak bir istisna nesnesi aldığını unutmayın. e.what(), "bad allocation"'u nasıl yazdırıyor? Dilimleneceğini düşündüm.

#include <iostream> 

int main() 
{ 
    try 
    { 
     int* p = new int[0x1F000000]; 
    } 
    catch(std::exception e) 
    { 
     std::cout << e.what() << std::endl; 
    } 
} 
+2

Programınıza = ~ 1.9375GB ayırmaya çalıştınız. 32bit derliyor musun? Makinende çok fazla RAM var mı? – FailedDev

+0

@GMan Derleyici, MS VS 2008 – Belloc

cevap

13

Visual Studio (Dinkumware?) Mesajı için dahili depolama † içeren std::exception bir uygulamasını kullanır. (Bir dize kabul eden standart olmayan bir kurucu ile tamamlayın.)

Bu nedenle, hata iletisini almak için sanal gönderime gerek yoktur, dilimlemeden kurtulur.

Daha ortodoks bir uygulama gerçekten türetilen nesne kesilmiş olduğundan genel bir özel durum iletisi yazdırır. (Etkili MS std::exception::what dönüş değeri uygulama tanımlı olduğu için bu yanlış bir şey var. std::exception ve std::runtime_error eşdeğer yaptı, ancak sonuçlarınızı açıklıyor.)


İç depolama † burada gevşek kullanılır. İç arabelleği yok, ancak bir const char* ve bir bool vardır. const char* iletiye (what() dönüş değeri) işaret eder ve bool arabelleğin silinmesi gerekip gerekmediğini belirten bir işarettir.

Şöyle:

class msvc_exception // for exposition 
{ 
public: 
    msvc_exception(const char* msg) : 
    mMsg(msg), 
    mDoDelete(false) 
    {} 

    msvc_exception(const std::string& msg) : 
    mMsg(copy_string(msg)), 
    mDoDelete(true) 
    {} 

    virtual ~msvc_exception() 
    { 
     if (mDoDelete) 
      delete [] mMsg; 
    } 

    virtual const char* what() const throw() 
    { 
     return mMsg ? mMsg : "unknown"; 
    } 

private: 
    const char* copy_string(const std::string& str) 
    { 
     const char* result = new char[str.size() + 1]; 

     std::copy(str.begin(), str.end(), result); 
     result[str.size()] = 0; // null-terminate 

     return result; 
    } 
}; 

Artık böyle olduğunu bad_alloc eser bkz: ileti taban sınıfta "var" çünkü

class msvc_bad_alloc : // for exposition 
     public msvc_exception 
    { 
    public: 
     msvc_bad_alloc() : 
     msvc_exception("bad_alloc") // note: a static string, no dynamic storage 
     {} 
    }; 

Dilimleme mesaj etkilemez.

Diğer derleyiciler, GCC ve LLVM gibi, biraz daha düz ileriye doğru uygulamak: Burada

class orthodox_exception 
{ 
public: 
    orthodox_exception(){} 
    virtual ~orthodox_exception() {} 

    virtual const char* what() const throw() 
    { 
     return "orthodox_exception"; 
    } 
}; 

class orthodox_bad_alloc : 
    public orthodox_exception 
{ 
public: 
    const char* what() const throw() 
    { 
     return "orthodox_bad_alloc"; 
    } 
}; 

, dilimleme sonucunuzu etkileyecektir. (Tüm bunlardan sonra: her zaman referansla yakalayın.)

+0

Yani, 'exception', karakter dizisinin tüm türetilmiş sınıfları için bir kopyasını saklı tuttuğunu söylüyorsunuz? – Belloc

+0

@ user1042389: Dilim biraz gevşek, düzenlememe izin ver. – GManNickG

+0

Şimdi oldukça açık. Çok teşekkürler. – Belloc

İlgili konular