SORU
15 Mayıs 2015, Cuma


Nasıl C kodu sonu

Eğer belirli bir koşul yerine C kodu çalışmıyor etmek istiyorum, ama bunu nasıl emin değilim. Yani sadece herhangi bir noktada eğer if deyimi doğruysa böyle bir kodu sonlandırma:

if (x==1)
{
    kill code;
}

CEVAP
15 Mayıs 2015, Cuma


Çeşitli yollar vardır, ama ilk nesne temizleme önemlidir, ve dolayısıyla neden std::exit C programcıları arasında dışlandığını neden anlamak gerekir.

DEMİRYOLU ve Gevşemek Yığını

C bir deyim basit bir dille nesne oluşturucu başlatma gerçekleştirmek ve yıkıcı temizleme gerektiği anlamına gelir RAII, denilen kullanır. Örnek std::ofstream sınıf [Mayıs] dosya açma sırasında kurucu, sonra kullanıcı çıkış işlemleri gerçekleştirir, ve nihayet sonunda kendi yaşam döngüsü, genellikle belirlenerek, kapsamı, yıkıcı denir aslında dosyayı kapatır ve temizler herhangi bir yazılı içerik içine yerleştirin.

Eğer yıkıcı ve dosya floş kapatmak için alamadım eğer doğru değilse ne olur?Kim bilir!Ama muhtemelen dosyasına yazmak için gereken tüm verileri yazmıyor.

Örneğin bu kod göz önünde bulundurun

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    std::unique_ptr<int> ptr(new int);
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

Her ihtimale olur:

  • Olasılık 1:Dönüş aslında os yaşam döngüsünün sonuna böylece kendi yıkıcı arayıp kapanış ve diske dosya kızarma tarafından uygun temizlik yapmayı bilir, o anki fonksiyon kapsam bırakır.
  • Olasılık 2:Bir özel durum üretiliyor da geçerli kapsamda nesnelerin yaşam döngüsü bakım, böylece uygun bir temizleme yapmaya götürür
  • Olasılık 3:Burada yığın gevşemek eylem girer! Olsa bile istisna atılır inner_mad sarıcı olacak olsa da, yığın mad main gerçekleştirmek için uygun temizlik, tüm nesneler çıkacak tahrip düzgün, dahil olmak üzere ptr os.
  • Olasılık 4:Peki, burada mı? exit C bir fonksiyon ve C cümleler ile haberdar ne de uyumlu değil.değilaynı kapsamda nesneler, os da dahil olmak üzere temizleme gerçekleştirin. Dosyanızı düzgün kapalı olmayacak ve bu nedenle içeriğin hiç içine yazılmış olabilir!
  • Diğer Olasılıklar:Sadece ana kapsamı, return 0 örtülü gerçekleştirme ve böylece 1, yani uygun bir temizleme imkanı aynı etkiye sahip olarak bırakır.

Ama ben sadece sana söylediği şey hakkında bu kadar emin olma (özellikle olasılık 2 ve 3); okumaya devam edin ve uygun bir istisna temizleme tabanlı gerçekleştirmek için nasıl öğreneceğiz.

Muhtemel Yollar İçinSonunda

Ana dönmek!

Mümkün olduğunca bunu yapmak; her ana uygun bir çıkış durumu döndürerek programınızdan geri dönmek için tercih etmelisiniz.

Programı arayan ve muhtemelen işletim sistemi, program yapmak gerekiyordu ne başarıyla yapmış olup olmadığını bilmek isteyebilir. Bu aynı sebepten geri götürmelisin sıfır veya EXIT_SUCCESS sinyal programı başarıyla sona erdirildi ve EXIT_FAILURE sinyal program sonlandırıldı başarısız, başka bir biçimde geri dönüş değeri uygulama tanımlı (/8 §18.5).

Ancak çağrı yığını içinde çok derin olabilir ve tüm dönen ağrılı olabilir...

[] Bir istisna

Bir özel durum üretiliyor uygun nesne temizleme, önceki kapsamında yığını, her nesnenin yıkıcı arayarak gevşemek kullanarak gerçekleştirir.

Ama işteav! Yığın gevşemek atılan bir özel durum işlenmiyor ne zaman yapılıp tanımlı uygulama(catch(...) madde)veya eğer çağrı ortasında noexcept bir işlevi varsa bile yığını. Bu ifade yer almaktadır§15.5.1 [hariç.Sonlandır]:

  1. Bazı durumlarda özel durum işleme daha az ince bir hata işleme teknikleri için terk edilmelidir. Durumlar Bunlar: [not:

    [...]

    ne zaman özel durum işleme mekanizması bulunamıyor işleyici için atılmış bir özel durum (15.3) veya arama için bir işleyici (15.3) karşılaşır dıştaki blok fonksiyonu ile noexcept-şartnameistisna (15.4) izin vermeyen, ya [...]

    [...]

  2. Bu gibi durumlarda,:: std Sonlandır () (18.8.3) denir. Eşleşen bir işleyici bulunduğu durumda, veya yığın çözülmemiş std önce olup olmadığını tanımlı uygulama::Sonlandır() denir[...]

Onu yakalamalıyız!

Bir istisna yapmak ve ana de yakalayın!

Yakalanmamış beri istisnalar yığın gevşemek gerçekleştirebilir(ve sonuç olarak uygun bir temizleme istemezler)ana özel durum yakalamak ve çıkış durumu (EXIT_SUCCESS EXIT_FAILURE) dönüş yapmamız gerek.

Muhtemelen iyi bir kurulum olur:

int main()
{
    /* ... */
    try
    {
        // Insert code that will return by throwing a exception.
    }
    catch(const std::exception&)  // Consider using a custom exception type for intentional
    {                             // throws. A good idea might be a `return_exception`.
        return EXIT_FAILURE;
    }
    /* ... */
}

[]:: Std çıkın

Bu yığın her türlü çözülme yapmaz, ve yığın üzerinde hiçbir canlı nesne kendi yıkıcı temizleme işlemleri için arayacak.

Bu zorunlu§3.6.1/4 [temel.başlayın.ınit]:

Geçerli blok çıkmadan, program sonlandırma (örneğin, işlev std çağırarak::exit(int) (18.5)) otomatik depolama süresi (12.4) ile herhangi bir nesne yok etmez. Std::çıkış statik veya iplik depolama süresi ile bir nesne imha sırasında bir programı sonuna kadar devam, programı tanımsız davranış var.

Düşünüyorum da, neden böyle bir şey yaptın? Kaç tane nesne acı bir şekilde zarar görmüş mü?

[Gibi] kötü diğer alternatifler

Programı sonlandırmak için başka yollar vardır(çökmesini dışında)tavsiye değil , ama. Sadece açıklama iyiliği için burada sunulan olacak. Nasıl dikkat edinnormal program sonlanmasıdeğilama bir yığın dinlenmek demekTamamişletim sistemi için devlet.

  • std::_Exit normal bir program sonlandırma neden olur, o kadar.
  • std::quick_exit normal bir program sonlandırma nedenleri ve std::at_quick_exit işleyicileri aramaları, başka bir temizlik yapılır.
  • std::exit normal bir program sonlandırma neden olur ve daha sonra std::atexit işleyicileri çağırır. Temizlikleri diğer türlü statik nesneler yıkıcılar " demek gibi yapılır.
  • std::abort olağandışı program sonlandırma nedenleri, temizleme işlemi gerçekleştirilir. Bu program gerçekten çok beklenmedik bir şekilde sonlandırılmış olur. Hiçbir şey ama anormal fesih hakkında OS sinyal. Bazı sistemler bu durumda çekirdek dökümü gerçekleştirmek.
  • std::terminate varsayılan std::abort aramalar std::terminate_handler çağırır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:
C++

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • emimusic

    emimusic

    10 Mart 2006
  • iBand IguJoo

    iBand IguJoo

    25 AĞUSTOS 2006
  • MrRandomSong

    MrRandomSong

    29 Kasım 2009