C / C ++ ukuran tumpukan maksimum program

115

Saya ingin melakukan DFS pada array 100 X 100. (Katakanlah elemen array mewakili node grafik) Jadi dengan asumsi kasus terburuk, kedalaman panggilan fungsi rekursif bisa naik hingga 10000 dengan setiap panggilan mengambil katakanlah 20 byte. Jadi apakah itu layak berarti apakah ada kemungkinan stackoverflow?

Berapa ukuran maksimum tumpukan di C / C ++?

Tentukan gcc untuk
1) cygwin di Windows
2) Unix

Apa batasan umumnya?

avd
sumber
11
Anda tahu bahwa Anda dapat menerapkan penelusuran pertama kedalaman tanpa rekursi, bukan?
Sebastian
4
Tidak, saya tidak tahu, tolong jelaskan.
rata
1
Saya telah membuat contoh kecil DFS tanpa rekursi dalam jawaban saya
Andreas Brinck
56
ditambah satu untuk pertanyaan tentang stack overflow yang sebenarnya
Sam Watkins
3
@SamWatkins ya, salah satu masalah terbesar bagi saya dengan nama Stack Overflow adalah saya mungkin mencari "stack overflow" di Google dan berakhir di situs ini, tetapi tidak selalu / kurang mungkin dalam pertanyaan tentang stack overflows ...
lalilulelost

Jawaban:

106

Dalam Visual Studio ukuran tumpukan default adalah 1 MB saya pikir, jadi dengan kedalaman rekursi 10.000 setiap bingkai tumpukan dapat paling banyak ~ 100 byte yang seharusnya cukup untuk algoritma DFS.

Kebanyakan kompiler termasuk Visual Studio memungkinkan Anda menentukan ukuran tumpukan. Pada beberapa (semua?) Linux rasa ukuran tumpukan bukan bagian dari yang dapat dieksekusi tetapi variabel lingkungan di OS. Anda kemudian dapat memeriksa ukuran tumpukan dengan ulimit -sdan mengaturnya ke nilai baru dengan misalnya ulimit -s 16384.

Berikut link dengan ukuran tumpukan default untuk gcc.

DFS tanpa rekursi:

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())
Andreas Brinck
sumber
12
Dan hanya untuk referensi, BFS sama kecuali Anda menggunakan FIFO, bukan tumpukan.
Steve Jessop
Ya, atau di STL-lingo gunakan std :: deque dengan pop_front / push_back
Andreas Brinck
DFS Anda dengan hasil stack akan berbeda dengan versi rekursi. Dalam beberapa kasus tidak masalah, tetapi dalam kasus lain (misalnya dalam urutan topologi) Anda akan mendapatkan hasil yang salah
spin_eight
Ya, batas default untuk VS memang 1MB. Info selengkapnya dan cara menyetel nilai berbeda dapat ditemukan di dokumentasi Microsoft: msdn.microsoft.com/en-us/library/tdkhxaks(v=vs.140).aspx
FrankS101
Saya lebih suka menggunakan struktur data tumpukan eksplisit untuk algoritme semacam itu, daripada rekursi, sehingga 1. tidak bergantung pada ukuran tumpukan sistem, 2. dapat mengubah algoritme untuk menggunakan struktur data yang berbeda misalnya antrean atau antrean prioritas tanpa membuang keluar semua kode.
Sam Watkins
47

tumpukan benang seringkali lebih kecil. Anda dapat mengubah default pada waktu tautan, atau mengubah pada waktu berjalan juga. Sebagai referensi, beberapa default adalah:

  • 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
pixelbeat
sumber
14
Ditentukan secara empiris oleh Bruno Haible lists.gnu.org/archive/html/bug-coreutils/2009-10/msg00262.html
pixelbeat
17

Tergantung platform, bergantung pada toolchain, bergantung pada ulimit, bergantung pada parameter .... Ini sama sekali tidak ditentukan, dan ada banyak properti statis dan dinamis yang dapat mempengaruhinya.

DrPizza
sumber
4
Tidak ada "batasan umum". Di Windows, dengan opsi linker VC ++ default dan perilaku CreateThread default, biasanya sekitar 1 MiB per utas. Di Linux, dengan pengguna yang tidak terbatas, saya percaya bahwa biasanya tidak ada batasan (tumpukan hanya dapat tumbuh ke bawah untuk menempati hampir seluruh ruang alamat). Pada dasarnya, jika Anda harus bertanya, Anda tidak boleh menggunakan tumpukan.
DrPizza
1
Pada sistem tertanam, Anda mungkin memiliki 4k atau kurang. Dalam hal ini Anda harus bertanya bahkan ketika menggunakan tumpukan itu wajar. Jawabannya biasanya mengangkat bahu Gallic.
Steve Jessop
1
Ah benar, juga sering terjadi pada mode kernel.
DrPizza
6

Ya, ada kemungkinan tumpukan meluap. Standar C dan C ++ tidak mendikte hal-hal seperti kedalaman tumpukan, yang umumnya merupakan masalah lingkungan.

Sebagian besar lingkungan pengembangan dan / atau sistem operasi yang layak akan memungkinkan Anda menyesuaikan ukuran tumpukan suatu proses, baik pada saat tautan atau waktu muat.

Anda harus menentukan OS dan lingkungan pengembangan yang Anda gunakan untuk bantuan yang lebih bertarget.

Misalnya, di Ubuntu Karmic Koala, default untuk gcc adalah 2M dicadangkan dan 4K berkomitmen tetapi ini dapat diubah saat Anda menautkan program. Gunakan --stackopsi lduntuk melakukan itu.

paxdiablo
sumber
2
@lex: tidak ada batasan umum. Itu tergantung pada banyak parameter.
Michael Foukarakis
@paxdiablo: Apa yang dimaksud dengan dilindungi dan berkomitmen?
rata
2
Cadangan adalah berapa banyak ruang alamat yang akan dialokasikan, komitmen adalah berapa banyak penyimpanan cadangan untuk dilampirkan. Dengan kata lain, memesan ruang alamat tidak berarti memori akan tetap ada saat Anda membutuhkannya. Jika Anda tidak pernah menggunakan lebih dari 4K stack, Anda tidak membuang-buang memori nyata untuk 1.6M lainnya. Jika Anda ingin menjamin akan ada cukup tumpukan, yang dipesan dan berkomitmen harus identik.
paxdiablo
2
@paxdiablo 2M - 4k bukan 1,6M. Hanya mengatakan. (membuat saya bingung saat 3 kali pertama saya membaca komentar Anda)
griffin
2
@griffin, pujian untuk orang pertama yang menangkapnya dalam 3+ tahun. Tentu saja maksud saya "sisanya" - saya akan menghindari angka yang sebenarnya agar tidak membuat kesalahan lain yang mungkin :-)
paxdiablo
5

Saya baru saja kehabisan tumpukan di tempat kerja, itu adalah database dan menjalankan beberapa utas, pada dasarnya pengembang sebelumnya telah melemparkan array besar ke tumpukan, dan tumpukan itu tetap rendah. Perangkat lunak ini disusun menggunakan Microsoft Visual Studio 2015.

Meskipun utas kehabisan tumpukan, utas gagal dan berlanjut secara diam-diam, itu hanya tumpukan meluap ketika datang untuk mengakses konten data di tumpukan.

Saran terbaik yang bisa saya berikan adalah untuk tidak mendeklarasikan array di stack - terutama dalam aplikasi yang kompleks dan terutama di thread, sebagai gantinya gunakan heap. Untuk itulah itu ada;)

Juga perlu diingat bahwa ini mungkin tidak langsung gagal saat mendeklarasikan tumpukan, tetapi hanya pada akses. Dugaan saya adalah bahwa kompiler menyatakan tumpukan di bawah jendela "secara optimis", yaitu akan menganggap bahwa tumpukan telah dideklarasikan dan berukuran cukup sampai digunakan dan kemudian menemukan bahwa tumpukan tidak ada.

Sistem operasi yang berbeda mungkin memiliki kebijakan deklarasi stack yang berbeda. Silakan tinggalkan komentar jika Anda tahu apa kebijakan ini.

Burung hantu
sumber
3

Saya tidak yakin apa yang Anda maksud dengan melakukan pencarian pertama yang mendalam pada array persegi panjang, tetapi saya berasumsi Anda tahu apa yang Anda lakukan.

Jika batas tumpukan adalah masalah, Anda harus dapat mengubah solusi rekursif Anda menjadi solusi berulang yang mendorong nilai antara ke tumpukan yang dialokasikan dari heap.

Dave Kirby
sumber