SORU
19 Mayıs 2015, Salı


Nasıl bir StackOverflowException algılanır?

Bir StackOverflowException olduğunu düşündüm soruyu sorduğumda sırayla mekanizması sonsuz uygulamaları çalıştırmak için önlemek için. Bu doğru değil. Bir 'KİT' algılanmaz - özel durum atılır yığın daha fazla bellek kapasitesine sahip değil.


Bu programlama dili için farklı cevapları olan genel bir soru.
Diller C den başka nasıl emin değilim# bir yığın taşması işlemek.

Özel Durumlar bugün yaşamakta olduğumu ve bir StackOverflowException tespit edilebilir hakkında düşünmeye devam ediyorum. Olası yığın derin 1000 aramalar ise (örneğin) ki, bu özel durum değil bence.
Belki bazı durumlarda doğru çünkü mantığı o kadar derin olacaktır.

Benim program sonsuz bir döngü algılama arkasındaki mantık nedir?

SOE Sınıfı: https://msdn.microsoft.com/de-de/library/system.stackoverflowexception(v=vs.110).aspx

Cross ref KİT sınıfında belirtilen: https://msdn.microsoft.com/de-de/library/system.reflection.emit.opcodes.localloc(v=vs.110).aspx

Not:
Ben sadece bu soru için stack-overflow etiketi eklendi ve açıklama çağrı yığını çok fazla bellek tüketir atılmış olması olduğunu söylüyor. Bunun anlamı eğer arama şey olamaz daha fazla mağaza eğer benim program mevcut yürütme konumuna tür yol ve bir yığın yaparyol bilgilerio zaman bu özel durum?

CEVAP
19 Mayıs 2015, Salı


Yığın uzaklıklarını aşıyor

Senin için kolaylaştırayım; ama bu aslında oldukça karmaşık... biraz burada genelleme Unutmayın.

Bildiğiniz gibi, çoğu dilde çağrı bilgi depolamak için yığın kullanın. Ayrıca Bkz: cdecl nasıl çalışır https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx. Eğer bir yöntemini çağırırsanız, yığın şeyler itin; eğer dönerseniz, bir şeyler yığını pop.

Özyineleme normal değil unutmayın 'inlined'. (Not: ben açıkça 'yineleme' burada değil, 'kuyruk özyineleme'; ikincisi çalışıyor '' ve büyümek değil yığın) git. dediği gibi

Bir yığın taşması tespit etmek için en kolay yolu bir yığın akım derinliği kontrol etmek için (örneğin kullanılan bayt) - ve eğer bir sınır isabet ederse, bir hata verir. Açıklamak hakkında bu 'sınır kontrolü': bu çekler yapılır normalde kullanarak koruma sayfaları; bunun anlamı, sınır kontrolleri değil normal olarak uygulanan ve eğer-sonra-başka çekleri (her ne kadar bazı uygulamalar var...).

Çoğu dilde, her iş parçacığı kendi yığını vardır.

Sonsuz döngü tespit edildi

Şimdi, burada bir süre haber alamadım bir soru. :-)

Temelde tüm sonsuz algılama döngüler Halting Problem çözmek için gerektirir. undecidable problem bir durum bu arada. Bu kesinlikle Derleyiciler tarafından yapılır.

Bu herhangi bir analiz yapamazsın anlamına gelmez; aslında, analiz biraz yapabilirsiniz. Ancak, bazen bazı şeyler sonsuza kadar çalıştırmak istediğiniz not (web server ana döngü gibi).

Diğer diller

Ayrıca ilginç... Fonksiyonel diller temelde yığını ile bağlı olan, yani özyineleme kullanın. (Yani, fonksiyonel diller de daha fazla veya daha az bir 'A' ve çıkmaz yığını.) goto gibi çalışır, kuyruk özyineleme kullanma eğiliminde " dedi

Ve sonra Mantıksal diller.. Peki şimdi nasıl emin değilim döngü sonsuza kadar o - muhtemelen sonuna kadar bir şey olmayacak değerlendirmek (çözüm bulunabilir). (Gerçi, muhtemelen bu dili... ) bağlıdır

Verimli, uyumsuz, devamı

İlginç bir konsept continuations denir düşünebilirsiniz. yield ilk hayata geçirildiği, gerçek uygulama devamı olarak düşünülen Microsoft duydum. Devamı için temelde izin için 'Kaydet' yığın, başka bir yerde devam ve 'geri' yığın geri bir sonraki nokta... (Yine, detaylar çok daha karmaşık bu; bu sadece temel fikir).

Ne yazık ki Microsoft bu fikir için neden hayal edebiliyorum ancak) gitmedi, ama bir Yardımcı Sınıf kullanarak gerçekleştirdi. Verim ve zaman uyumsuz C# geçici bir sınıf ekleme ve sınıf içinde tüm yerel değişkenler staj. Eğer dediğiniz bir yöntem olan bir 'verim' ya da 'uyumsuz', aslında oluşturmak bir yardımcı sınıfı (içinden yöntemi çağrısı ve it yığını bu itilmiş üzerine yığını. Öbek üzerinde itti sınıf işlevi (yield Bu numaralandırma uygulaması gibi) sahiptir. Bu yapılacak en doğru programı MoveNext çağrıldığında devam etmelidir konumu (bazı devlet kimliği gibi) saklayan bir devlet değişkeni kullanarak. Bir şube (anahtar) bu KİMLİĞİ kullanarak gerisini halleder. Bu mekanizma hiçbir şey yapmaz unutmayın 'özel' yığın kendisi çalışır, sınıflar ve yöntemler kullanılarak aynı uygulayabilirsiniz bu şekilde (sadece daha yazmayı içerir :-)).

Çözme bir yığın manuel yığını ile doludur

Ben her zaman iyi bir taşkın dolgu gibi. Bir resim varsa, bu yanlış... böyle yaparsan seni yinelenen çağrı çok verecektir:

public void FloodFill(int x, int y, int color)
{
    // Wait for the crash to happen...
    if (Valid(x,y))
    {
        SetPixel(x, y, color);
        FloodFill(x - 1, y, color);
        FloodFill(x   1, y, color);
        FloodFill(x, y - 1, color);
        FloodFill(x, y   1, color);
    }
}

Hiçbir şey bu kodu ama bir sorun var. Bütün işi yapar, ama bizim bir şekilde alır yığını. Manuel yığını olan uygulama temelde aynı olsa da bu çözer:

public void FloodFill(int x, int y, int color)
{
    Stack<Tuple<int, int>> stack = new Stack<Tuple<int, int>>();
    stack.Push(new Tuple<int, int>(x, y));
    while (stack.Count > 0)
    {
        var current = stack.Pop();

        int x2 = current.Item1;
        int y2 = current.Item2;

        // "Recurse"
        if (Valid(x2, y2))
        {
            SetPixel(x2, y2, color);
            stack.Push(new Tuple<int, int>(x2-1, y2));
            stack.Push(new Tuple<int, int>(x2 1, y2));
            stack.Push(new Tuple<int, int>(x2, y2-1));
            stack.Push(new Tuple<int, int>(x2, y2 1));
        }
    }
}

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CommonArtisan

    CommonArtisa

    7 Temmuz 2012
  • KIT KAT

    KIT KAT

    3 EKİM 2005
  • MrDevin521

    MrDevin521

    18 Temmuz 2010