C / C ++ programın maksimum yığın boyutu


115

100 X 100 dizisinde DFS yapmak istiyorum. (Dizinin elemanlarının grafik düğümlerini temsil ettiğini söyleyin) Yani en kötü durumda, özyinelemeli işlev çağrılarının derinliği 10000'e kadar çıkabilir ve her çağrı 20 bayta kadar çıkabilir. Öyleyse bu, bir yığın taşması olasılığı olduğu anlamına gelir mi?

C / C ++ 'da maksimum yığın boyutu nedir?

Lütfen her ikisi için de gcc için belirtin
1) Windows'ta cygwin
2) Unix

Genel sınırlar nelerdir?


11
Özyineleme olmadan önce derinlik araması yapabileceğinizi biliyorsunuz, değil mi?
Sebastian

4
Hayır bilmiyorum, lütfen açıkla.
avd

1
Cevabımda yinelemesiz küçük bir DFS örneği yaptım
Andreas Brinck

56
artı gerçek yığın taşmasıyla ilgili bir soru için
Sam Watkins

3
@SamWatkins evet, Stack Overflow adıyla benim için en büyük sorunlardan biri, Google'da "yığın taşması" na bakıp bu web sitesine gidebilmem, ancak yığın taşmasıyla ilgili sorularda mutlaka / daha az olası değil ...
lalilulelost

Yanıtlar:


106

Visual Studio'da varsayılan yığın boyutunun 1 MB olduğunu düşünüyorum, bu nedenle 10.000 özyineleme derinliği ile her yığın çerçevesi, bir DFS algoritması için yeterli olması gereken en fazla ~ 100 bayt olabilir.

Visual Studio dahil çoğu derleyici, yığın boyutunu belirtmenize izin verir. Bazı (tümü?) Linux tatlarında, yığın boyutu çalıştırılabilir dosyanın bir parçası değil, işletim sistemindeki bir ortam değişkeni. Daha sonra yığın boyutunu ile kontrol edebilir ulimit -sve örneğin ile yeni bir değere ayarlayabilirsiniz ulimit -s 16384.

Gcc için varsayılan yığın boyutlarını içeren bir bağlantı burada .

Özyinelemesiz DFS:

std::stack<Node> dfs;
dfs.push(start);
do {
    Node top = dfs.top();
    if (top is what we are looking for) {
       break;
    }
    dfs.pop();
    for (outgoing nodes from top) {
        dfs.push(outgoing node);
    }
} while (!dfs.empty())

12
Ve sadece referans için, bir BFS, yığın yerine bir FIFO kullanmanız dışında aynıdır.
Steve Jessop

Evet, veya STL-dilinde pop_front / push_back ile std :: deque kullanın
Andreas Brinck

yığın sonuçları olan DFS'niz özyineleme sürümünden farklı olacaktır. Bazı durumlarda önemli değildir, ancak diğerlerinde (örneğin topolojik sıralamada) yanlış sonuçlar alırsınız
spin_eight

Evet, VS için varsayılan sınır gerçekten 1MB'dir. Daha fazla bilgi ve farklı bir değer ayarlamanın yolu Microsoft belgelerinde bulunabilir: msdn.microsoft.com/en-us/library/tdkhxaks(v=vs.140).aspx
FrankS101

Bu tür algoritmalar için özyineleme yerine açık bir yığın veri yapısı kullanmayı tercih ederim, böylece 1. sistem yığınının boyutuna bağlı kalmaz, 2. algoritmayı farklı bir veri yapısı kullanacak şekilde değiştirebilir, örn. Kuyruk veya öncelik sırası atmadan tüm kodu dışarı.
Sam Watkins

47

iş parçacığı yığınları genellikle daha küçüktür. Varsayılanı bağlantı zamanında değiştirebilir veya çalışma zamanında da değiştirebilirsiniz. Referans için bazı varsayılanlar şunlardır:

  • glibc i386, x86_64 7.4 MB
  • Tru64 5.1 5.2 MB
  • Cygwin 1.8 MB
  • Solaris 7..10 1 MB
  • MacOS X 10.5 460 KB
  • AIX 5 98 KB
  • OpenBSD 4.0 64 KB
  • HP-UX 11 16 KB


17

Platforma bağlı, araç zincirine bağlı, ultra bağımlı, parametreye bağımlı .... Hiç belirtilmemiştir ve onu etkileyebilecek birçok statik ve dinamik özellik vardır.


4
"Genel sınırlar" yoktur. Windows'ta, varsayılan VC ++ bağlayıcı seçenekleri ve varsayılan CreateThread davranışı ile, tipik olarak iş parçacığı başına 1 MiB civarında. Sınırsız bir kullanıcıya sahip Linux'ta, tipik olarak bir sınır olmadığına inanıyorum (yığın, neredeyse tüm adres alanını kaplayacak şekilde aşağı doğru büyüyebilir). Temel olarak, sormanız gerekiyorsa, yığını kullanmamalısınız.
DrPizza

1
Gömülü sistemlerde 4k veya daha azına sahip olabilirsiniz. Bu durumda yığını kullanmak mantıklı olsa bile sormanız gerekir. Cevap genellikle bir Galya omuz silkme.
Steve Jessop

1
Ah doğru, aynı zamanda çekirdek kipinde de sıklıkla geçerli.
DrPizza

6

Evet, yığın taşması olasılığı vardır. C ve C ++ standardı yığın derinliği gibi şeyleri dikte etmez, bunlar genellikle çevresel bir sorundur.

Uygun geliştirme ortamlarının ve / veya işletim sistemlerinin çoğu, bağlantı veya yükleme zamanında bir işlemin yığın boyutunu uyarlamanıza izin verir.

Daha iyi hedeflenmiş yardım için hangi işletim sistemini ve geliştirme ortamını kullandığınızı belirtmelisiniz.

Örneğin, Ubuntu Karmic Koala altında, gcc için varsayılan 2M ayrılmış ve 4K taahhütlüdür ancak bu, programı bağladığınızda değiştirilebilir. Bunu yapma --stackseçeneğini kullanın ld.


2
@lex: genel bir sınır yoktur. Bir çok parametreye bağlıdır.
Michael Foukarakis

@paxdiablo: Ayrılmış ve kararlı kelimesinin anlamı nedir?
AvD

2
Ayrılan, ne kadar adres alanı tahsis edileceğidir, taahhüt edilen ise yedek depolamanın ne kadar ekleneceğidir. Başka bir deyişle, adres alanı ayırmak, belleğin ihtiyacınız olduğunda orada olacağı anlamına gelmez. Asla 4K yığınından fazlasını kullanmazsanız, diğer 1,6 milyon için gerçek belleği boşa harcamazsınız. Yeterli yığın olacağını garanti etmek istiyorsanız, ayrılmış ve kaydedilmiş aynı olmalıdır.
paxdiablo

3
@paxdiablo 2M - 4k, 1.6M değil. Sadece söylüyorum. (yorumunuzu okuduğum ilk 3 sefer kafamı karıştırdı)
griffin

2
@griffin, bunu 3+ yıl içinde ilk yakalayan kişi için tebrikler. Elbette "geri kalanı" demek istedim - başka bir olası hata yapmamak için gerçek rakamlardan kaçınacağım :-)
paxdiablo

5

Yığın işim bitti, bir veritabanıydı ve bazı iş parçacıkları çalıştırıyordu, temelde önceki geliştirici yığına büyük bir dizi atmıştı ve yığın yine de düşüktü. Yazılım, Microsoft Visual Studio 2015 kullanılarak derlenmiştir.

İş parçacığı yığın bitmiş olsa da sessizce başarısız oldu ve devam etti, yalnızca yığındaki verilerin içeriğine erişmeye geldiğinde yığın taştı.

Verebileceğim en iyi tavsiye, özellikle karmaşık uygulamalarda ve özellikle iş parçacığında yığın üzerinde dizi bildirmemek, bunun yerine yığın kullanın. Bunun için var;)

Ayrıca yığını bildirirken hemen başarısız olmayabileceğini, yalnızca erişimde başarısız olabileceğini unutmayın. Tahminimce, derleyici yığını pencereler altında "iyimser" olarak ilan eder, yani yığının bildirildiğini ve onu kullanmaya gelene kadar yeterince boyutlandırıldığını varsayar ve sonra yığının orada olmadığını anlar.

Farklı işletim sistemlerinin farklı yığın bildirim ilkeleri olabilir. Bu politikaların ne olduğunu biliyorsanız lütfen bir yorum bırakın.


3

Dikdörtgensel bir dizide derinlemesine arama yaparak ne demek istediğinizden emin değilim, ama ne yaptığınızı bildiğinizi varsayıyorum.

Yığın sınırı bir sorunsa, özyinelemeli çözümünüzü, ara değerleri öbekten ayrılan bir yığına iten yinelemeli bir çözüme dönüştürebilmeniz gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.