"Yığın taşması" nasıl gerçekleşir ve bunu nasıl engellersiniz?


100

Bir yığın taşması nasıl meydana gelir ve bunun olmamasını sağlamanın en iyi yolları nelerdir veya özellikle web sunucularında birini önlemenin yolları nelerdir, ancak diğer örnekler de ilginç olabilir mi?


Sanırım bu soruyu sormak için stackoverflow.com'dan daha iyi bir yer olamaz;)
gignu

Yanıtlar:


127

Yığın

Bu bağlamda bir yığın, programınız çalışırken verileri yerleştirdiğiniz son giren, ilk çıkar arabelleğidir. Son giren, ilk çıkar (LIFO), koyduğunuz son şeyin her zaman ilk çıkardığınız şey olduğu anlamına gelir - yığına 2 öğe, 'A' ve sonra 'B' iterseniz, o zaman ilk çıkardığınız şey yığın dışı 'B' ve sonraki şey 'A' olacaktır.

Kodunuzda bir işlevi çağırdığınızda, işlev çağrısından sonraki bir sonraki talimat yığında depolanır ve işlev çağrısı tarafından üzerine yazılabilecek herhangi bir depolama alanı. Çağırdığınız işlev, kendi yerel değişkenleri için daha fazla yığın kullanabilir. Tamamlandığında, kullandığı yerel değişken yığın alanını boşaltır ve ardından önceki işleve geri döner.

Yığın taşması

Yığın taşması, yığın için programınızın kullanması gerekenden daha fazla bellek kullandığınızda ortaya çıkar. Gömülü sistemlerde, yığın için yalnızca 256 bayta sahip olabilirsiniz ve her işlev 32 bayt alıyorsa, yalnızca işlev çağrıları 8 derin - işlev 1 çağrıları işlev 2, işlev 3'ü çağıran işlev 4'ü çağıran ... işlev 9'u çağıran işlev 8, ancak işlev 9 yığının dışındaki belleğin üzerine yazar. Bu, bellek, kod vb. Üzerine yazabilir.

Birçok programcı bu hatayı, daha sonra B işlevini, daha sonra C işlevini ve ardından A işlevini çağıran işlev A işlevini çağırarak yapar. Çoğu zaman işe yarayabilir, ancak yalnızca bir kez yanlış giriş sonsuza dek o çemberde kalmasına neden olur bilgisayar yığının aşırı üflendiğini anlayana kadar.

Yinelemeli işlevler de bunun bir nedenidir, ancak yinelemeli yazıyorsanız (yani işleviniz kendisini çağırıyorsa), bunun farkında olmanız ve sonsuz özyinelemeyi önlemek için statik / global değişkenler kullanmanız gerekir.

Genel olarak, kullandığınız işletim sistemi ve programlama dili yığını yönetir ve bu sizin kontrolünüzde değildir. İşlev çağrılarınızın ne kadar derinlere gittiğini görmek ve amaçlanmayan döngüleri ve özyinelemeleri tespit etmek için çağrı grafiğinize (ana işlevinizden her bir işlevin ne çağırdığını gösteren bir ağaç yapısı) bakmalısınız. Kasıtlı döngülerin ve özyinelemenin, birbirlerini çok fazla aradıklarında hata yapmak için yapay olarak kontrol edilmesi gerekir.

İyi programlama uygulamalarının, statik ve dinamik testlerin ötesinde, bu üst düzey sistemlerde yapabileceğiniz pek bir şey yoktur.

Gömülü sistemler

Gömülü dünyada, özellikle yüksek güvenilirlik kodunda (otomotiv, uçak, uzay) kapsamlı kod incelemeleri ve kontrolleri yaparsınız, ancak aynı zamanda aşağıdakileri de yaparsınız:

  • Özyinelemeye ve döngülere izin verme - politika ve test tarafından zorunlu kılınmıştır
  • Kodu ve yığını birbirinden uzakta tutun (kod flash'ta, RAM'de yığın ve asla ikili birbirini karşılamayacak)
  • Yığının etrafına koruma bantları yerleştirin - sihirli bir sayı ile doldurduğunuz boş bellek alanı (genellikle bir yazılım kesme talimatı, ancak burada birçok seçenek vardır) ve saniyede yüzlerce veya binlerce kez emin olmak için koruma bantlarına bakarsınız. üzerine yazılmamış.
  • Bellek koruması kullanın (yani yığın üzerinde çalıştırma yok, yığının hemen dışında okuma veya yazma yok)
  • Kesmeler ikincil işlevleri çağırmaz - bayrakları ayarlar, verileri kopyalar ve uygulamanın işlenmesini sağlamasına izin verir (aksi takdirde işlev çağrısı ağacınızda 8 derinlik elde edebilir, bir kesinti yaşayabilir ve daha sonra işlevin içinde başka birkaç işlevi görüntüleyebilirsiniz. patlamaya neden olan kesinti). Birkaç çağrı ağacınız var - biri ana işlemler için ve biri her kesinti için. Sözünüz kesilirse ... ejderhalar vardır ...

Üst düzey diller ve sistemler

Ancak yüksek seviyeli dillerde işletim sistemlerinde çalışır:

  • Yerel değişken depolamanızı azaltın (yerel değişkenler yığında depolanır - derleyiciler bu konuda oldukça akıllı olsalar da, arama ağacınız sığ ise bazen yığına büyük yereller koyarlar)
  • Özyinelemeden kaçının veya kesinlikle sınırlayın
  • Programlarınızı çok daha küçük ve daha küçük işlevlere bölmeyin - yerel değişkenleri saymasa bile, her işlev çağrısı yığın üzerinde 64 bayta kadar tüketir (32 bit işlemci, CPU kayıtlarının, bayrakların, vb. Yarısından tasarruf)
  • Çağrı ağacınızı sığ tutun (yukarıdaki ifadeye benzer)

Web sunucuları

Yığını kontrol edip edemeyeceğiniz, hatta görebileceğiniz, sahip olduğunuz 'korumalı alana' bağlıdır. Web sunucularına diğer yüksek seviyeli dil ve işletim sistemlerinde olduğu gibi davranma şansınız yüksektir - bu büyük ölçüde sizin elinizde değildir, ancak kullandığınız dili ve sunucu yığınını kontrol edin. İse örneğin SQL sunucusu üzerinde yığın darbe mümkündür.

-Adam


9

Gerçek kodda yığın taşması çok nadiren gerçekleşir. Meydana geldiği çoğu durum, sonlandırmanın unutulduğu tekrarlamalardır. Ancak, yüksek iç içe geçmiş yapılarda, örneğin özellikle büyük XML belgelerinde nadiren ortaya çıkabilir. Buradaki tek gerçek yardım, çağrı yığını yerine açık bir yığın nesnesi kullanmak için kodu yeniden düzenlemektir.


7

Çoğu insan size bir çıkış yolu olmadan özyinelemeyle yığın taşmasının meydana geldiğini söyleyecektir - ancak çoğunlukla doğru olsa da, yeterince büyük veri yapılarıyla çalışıyorsanız, düzgün bir özyineleme çıkış yolu bile size yardımcı olmaz.

Bu durumda bazı seçenekler:


7

Jeff ve Joel dünyaya teknik sorulara yanıt bulabilecekleri daha iyi bir yer vermek istediklerinde yığın taşması meydana gelir. Bu yığının taşmasını önlemek için artık çok geç. O "diğer site", dağınık olmayarak onu engelleyebilirdi. ;)


6

Sonsuz özyineleme, yığın taşması hatası almanın yaygın bir yoludur. Önlemek için - her zaman emin olun bir çıkış yolu var olacak vurulacak. :-)

Yığın taşması elde etmenin başka bir yolu (en azından C / C ++ 'da) yığın üzerinde çok büyük bir değişken bildirmektir.

char hugeArray[100000000];

Bunu yapacak.


Hangi dili kullanıyorsun C'de, bu neredeyse kesin olarak bir yığın taşmasına neden olacaktır. C # 'da, dizinin yığında değil yığın üzerinde tahsis edilmesi nedeniyle olmayacaktır. Pratikte buna bir örnek olarak şu soruyu görün: stackoverflow.com/questions/571945/…
Matt Dillard

4

Genellikle yığın taşması, sonsuz özyinelemeli çağrının sonucudur (günümüzde standart bilgisayarlarda normal bellek miktarı göz önüne alındığında).

Bir metoda, işleve veya prosedüre çağrı yaptığınızda, "standart" yol veya çağrı yapmak şunlardan oluşur:

  1. Çağrının dönüş yönünü yığına itmek (çağrıdan sonraki cümle budur)
  2. Genellikle dönüş değeri alanı yığına ayrılır
  3. Her parametrenin yığına itilmesi (sıra farklılaşır ve her derleyiciye bağlıdır, ayrıca bazıları performans iyileştirmeleri için bazen CPU kayıtlarında depolanır)
  4. Gerçek aramayı yapmak.

Bu nedenle, genellikle bu, parametrelerin sayısı ve türünün yanı sıra makine mimarisine bağlı olarak birkaç bayt alır.

Özyinelemeli aramalar yapmaya başlarsanız, yığının büyümeye başlayacağını göreceksiniz. Şimdi, yığın genellikle bellekte öyle bir şekilde saklanır ki öbeğin tersi yönde büyür, böylece çok sayıda çağrı "geri gelmeden" yığın dolmaya başlar.

Şimdi, daha eski zamanlarda yığın taşması, sadece bunun gibi mevcut tüm bellekleri aştığınız için gerçekleşebilirdi. Kapsam dışında kalan sanal bellek modeliyle (X86 sisteminde 4 GB'a kadar), bu nedenle genellikle bir yığın taşması hatası alırsanız, sonsuz özyinelemeli çağrı arayın.


4

Ne? Sonsuz bir döngü içinde olanlar için kimsenin sevgisi yok mu?

do
{
  JeffAtwood.WritesCode();
} while(StackOverflow.MakingMadBank.Equals(false));

2
Bu sonsuz bir döngü, yığın taşması değil
Eddie Curtis

3

Doğrudan bir özyinelemeden (örneğin Fibonacci(1000000)) elde ettiğiniz yığın taşması biçiminin yanı sıra, birçok kez deneyimlediğim daha ince bir biçimi, dolaylı özyinelemedir; burada bir işlev başka bir işlevi çağırır, başka bir işlevi çağırır, sonra da bu işlevler ilkini yeniden çağırır.

Bu genellikle olaylara yanıt olarak çağrılan ancak kendileri yeni olaylar oluşturabilen işlevlerde ortaya çıkabilir, örneğin:

void WindowSizeChanged(Size& newsize) {
  // override window size to constrain width
    newSize.width=200;
    ResizeWindow(newSize);
}

Bu durumda, çağrı , siz yığın bitene kadar yeniden çağrılan geri çağrının yeniden tetiklenmesine ResizeWindowneden olabilir . Bu gibi durumlarda, genellikle yığın çerçevesi dönene kadar olaya yanıt vermeyi ertelemeniz gerekir, örneğin bir mesaj göndererek.WindowSizeChanged()ResizeWindow


2

Bunun "bilgisayar korsanlığı" ile etiketlendiğini göz önünde bulundurarak, bahsettiği "yığın taşması" nın, buradaki diğer yanıtların çoğunda atıfta bulunulanlar gibi daha yüksek seviyeli bir yığın taşması değil, bir çağrı yığını taşması olduğundan şüpheleniyorum. Web uygulamalarının tipik olarak yazıldığı .NET, Java, Python, Perl, PHP, vb. Gibi yönetilen veya yorumlanan ortamlar için gerçekten geçerli değildir, bu nedenle tek riskiniz, muhtemelen yazılan web sunucusunun kendisidir. C veya C ++.

Bu konuya göz atın:

/programming/7308/what-is-a-good-starting-point-for-learning-buffer-overflow


1

En yaygın Fibonacci sayısını, yani 1, 1, 2, 3, 5 ..... alırken yığın taşması sorununu yeniden yarattım, yani fib (1) = 1 veya fib (3) = 2 .. fib (n ) = ??.

n için, ilgileneceğimizi varsayalım - ya n = 100.000 ise, o zaman karşılık gelen Fibonacci sayısı ne olur?

Tek döngü yaklaşımı aşağıdaki gibidir -

package com.company.dynamicProgramming;

import java.math.BigInteger;

public class FibonacciByBigDecimal {

    public static void main(String ...args) {

        int n = 100000;
        BigInteger[] fibOfnS = new BigInteger[n + 1];

        System.out.println("fibonacci of "+ n + " is : " + fibByLoop(n));
    }


    static BigInteger fibByLoop(int n){

        if(n==1 || n==2 ){
            return BigInteger.ONE;
        }

        BigInteger fib = BigInteger.ONE;
        BigInteger fip = BigInteger.ONE;


        for (int i = 3; i <= n; i++){

            BigInteger p = fib;
            fib = fib.add(fip);
            fip = p;
        }

        return fib;
    }

}

bu oldukça basittir ve sonuç -

fibonacci of 100000 is : 2597406934722172416615503402127591541488048538651769658472477070395253454351127368626555677283671674475463758722307443211163839947387509103096569738218830449305228763853133492135302679278956701051276578271635608073050532200243233114383986516137827238124777453778337299916214634050054669860390862750996639366409211890125271960172105060300350586894028558103675117658251368377438684936413457338834365158775425371912410500332195991330062204363035213756525421823998690848556374080179251761629391754963458558616300762819916081109836526352995440694284206571046044903805647136346033000520852277707554446794723709030979019014860432846819857961015951001850608264919234587313399150133919932363102301864172536477136266475080133982431231703431452964181790051187957316766834979901682011849907756686456845066287392485603914047605199550066288826345877189410680370091879365001733011710028310473947456256091444932821374855573864080579813028266640270354294412104919995803131876805899186513425175959911520563155337703996941035518275274919959802257507902037798103089922984996304496255814045517000250299764322193462165366210841876745428298261398234478366581588040819003307382939500082132009374715485131027220817305432264866949630987914714362925554252624043999615326979876807510646819068792118299167964409178271868561702918102212679267401362650499784968843680975254700131004574186406448299485872551744746695651879126916993244564817673322257149314967763345846623830333820239702436859478287641875788572910710133700300094229333597292779191409212804901545976262791057055248158884051779418192905216769576608748815567860128818354354292307397810154785701328438612728620176653953444993001980062953893698550072328665131718113588661353747268458543254898113717660519461693791688442534259478126310388952047956594380715301911253964847112638900713362856910155145342332944128435722099628674611942095166100230974070996553190050815866991144544264788287264284501725332048648319457892039984893823636745618220375097348566847433887249049337031633826571760729778891798913667325190623247118037280173921572390822769228077292456662750538337500692607721059361942126892030256744356537800831830637593334502350256972906515285327194367756015666039916404882563967693079290502951488693413799125174856667074717514938979038653338139534684837808612673755438382110844897653836848318258836339917310455850905663846202501463131183108742907729262215943020429159474030610183981685506695026197376150857176119947587572212987205312060791864980361596092339594104118635168854883911918517906151156275293615849000872150192226511785315089251027528045151238603792184692121533829287136924321527332714157478829590260157195485316444794546750285840236000238344790520345108033282013803880708980734832620122795263360677366987578332625485944906021917368867786241120562109836985019729017715780112040458649153935115783499546100636635745448508241888279067531359950519206222976015376529797308588164873117308237059828489404487403932053592935976454165560795472477862029969232956138971989467942218727360512336559521133108778758228879597580320459608479024506385194174312616377510459921102486879496341706862092908893068525234805692599833377510390101316617812305114571932706629167125446512151746802548190358351688971707570677865618800822034683632101813026232996027599403579997774046244952114531588370357904483293150007246173417355805567832153454341170020258560809166294198637401514569572272836921963229511187762530753402594781448204657460288485500062806934811398276016855584079542162057543557291510641537592939022884356120792643705560062367986544382464373946972471945996555795505838034825597839682776084731530251788951718630722761103630509360074262261717363058613291544024695432904616258691774630578507674937487992329181750163484068813465534370997589353607405172909412697657593295156818624747127636468836551757018353417274662607306510451195762866349922848678780591085118985653555434958761664016447588028633629704046289097067736256584300235314749461233912068632146637087844699210427541569410912246568571204717241133378489816764096924981633421176857150311671040068175303192115415611958042570658693127276213710697472226029655524611053715554532499750843275200199214301910505362996007042963297805103066650638786268157658772683745128976850796366371059380911225428835839194121154773759981301921650952140133306070987313732926518169226845063443954056729812031546392324981793780469103793422169495229100793029949237507299325063050942813902793084134473061411643355614764093104425918481363930542369378976520526456347648318272633371512112030629233889286487949209737847861884868260804647319539200840398308008803869049557419756219293922110825766397681361044490024720948340326796768837621396744075713887292863079821849314343879778088737958896840946143415927131757836511457828935581859902923534388888846587452130838137779443636119762839036894595760120316502279857901545344747352706972851454599861422902737291131463782045516225447535356773622793648545035710208644541208984235038908770223039849380214734809687433336225449150117411751570704561050895274000206380497967960402617818664481248547269630823473377245543390519841308769781276565916764229022948181763075710255793365008152286383634493138089971785087070863632205869018938377766063006066757732427272929247421295265000706646722730009956124191409138984675224955790729398495608750456694217771551107346630456603944136235888443676215273928597072287937355966723924613827468703217858459948257514745406436460997059316120596841560473234396652457231650317792833860590388360417691428732735703986803342604670071717363573091122981306903286137122597937096605775172964528263757434075792282180744352908669606854021718597891166333863858589736209114248432178645039479195424208191626088571069110433994801473013100869848866430721216762473119618190737820766582968280796079482259549036328266578006994856825300536436674822534603705134503603152154296943991866236857638062351209884448741138600171173647632126029961408561925599707566827866778732377419444462275399909291044697716476151118672327238679208133367306181944849396607123345271856520253643621964198782752978813060080313141817069314468221189275784978281094367751540710106350553798003842219045508482239386993296926659221112742698133062300073465628498093636693049446801628553712633412620378491919498600097200836727876650786886306933418995225768314390832484886340318940194161036979843833346608676709431643653538430912157815543512852077720858098902099586449602479491970687230765687109234380719509824814473157813780080639358418756655098501321882852840184981407690738507369535377711880388528935347600930338598691608289335421147722936561907276264603726027239320991187820407067412272258120766729040071924237930330972132364184093956102995971291799828290009539147382437802779051112030954582532888721146170133440385939654047806199333224547317803407340902512130217279595753863158148810392952475410943880555098382627633127606718126171022011356181800775400227516734144169216424973175621363128588281978005788832454534581522434937268133433997710512532081478345067139835038332901313945986481820272322043341930929011907832896569222878337497354301561722829115627329468814853281922100752373626827643152685735493223028018101449649009015529248638338885664893002250974343601200814365153625369199446709711126951966725780061891215440222487564601554632812091945824653557432047644212650790655208208337976071465127508320487165271577472325887275761128357592132553934446289433258105028633583669291828566894736223508250294964065798630809614341696830467595174355313224362664207197608459024263017473392225291248366316428006552870975051997504913009859468071013602336440164400179188610853230764991714372054467823597211760465153200163085336319351589645890681722372812310320271897917951272799656053694032111242846590994556380215461316106267521633805664394318881268199494005537068697621855231858921100963441012933535733918459668197539834284696822889460076352031688922002021931318369757556962061115774305826305535862015637891246031220672933992617378379625150999935403648731423208873977968908908369996292995391977217796533421249291978383751460062054967341662833487341011097770535898066498136011395571584328308713940582535274056081011503907941688079197212933148303072638678631411038443128215994936824342998188719768637604496342597524256886188688978980888315865076262604856465004322896856149255063968811404400429503894245872382233543101078691517328333604779262727765686076177705616874050257743749983775830143856135427273838589774133526949165483929721519554793578923866762502745370104660909382449626626935321303744538892479216161188889702077910448563199514826630802879549546453583866307344423753319712279158861707289652090149848305435983200771326653407290662016775706409690183771201306823245333477966660525325490873601961480378241566071271650383582257289215708209369510995890132859490724306183325755201208090007175022022949742801823445413711916298449914722254196594682221468260644961839254249670903104007581488857971672246322887016438403908463856731164308169537326790303114583680575021119639905615169154708510459700542098571797318015564741406172334145847111268547929892443001391468289103679179216978616582489007322033591376706527676521307143985302760988478056216994659655461379174985659739227379416726495377801992098355427866179123126699374730777730569324430166839333011554515542656864937492128687049121754245967831132969248492466744261999033972825674873460201150442228780466124320183016108232183908654771042398228531316559685688005226571474428823317539456543881928624432662503345388199590085105211383124491861802624432195540433985722841341254409411771722156867086291742124053110620522842986199273629406208834754853645128123279609097213953775360023076765694208219943034648783348544492713539450224591334374664937701655605763384697062918725745426505879414630176639760457474311081556747091652708748125267159913793240527304613693961169892589808311906322510777928562071999459487700611801002296132304588294558440952496611158342804908643860880796440557763691857743754025896855927252514563404385217825890599553954627451385454452916761042969267970893580056234501918571489030418495767400819359973218711957496357095967825171096264752068890806407651445893132870767454169607107931692704285168093413311046353506242209810363216771910420786162184213763938194625697286781413636389620123976910465418956806197323148414224550071617215851321302030684176087215892702098879108938081045903397276547326416916845445627600759561367103584575649094430692452532085003091068783157561519847567569191284784654692558665111557913461272425336083635131342183905177154511228464455136016013513228948543271504760839307556100908786096663870612278690274831819331606701484957163004705262228238406266818448788374548131994380387613830128859885264201992286188208499588640888521352501457615396482647451025902530743172956899636499615707551855837165935367125448515089362904567736630035562457374779100987992499146967224041481601289530944015488942613783140087804311431741858071826185149051138744831358439067228949408258286021650288927228387426432786168690381960530155894459451808735197246008221529343980828254126128257157209350985382800738560472910941184006084485235377833503306861977724501886364070344973366473100602018128792886991861824418453968994777259482169137133647470453172979809245844361129618997595696240971845564020511432589591844724920942930301651488713079802102379065536525154780298059407529440513145807551537794861635879901158192019808879694967187448224156836463534326160242632934761634458163890163805123894184523973421841496889262398489648642093409816681494771155177009562669029850101513537599801272501241971119871526593747484778935488777815192931171431167444773882941064615028751327709474504763922874890662989841540259350834035142035136168819248238998027706666916342133424312054507359388616687691188185776118135771332483965209882085982391298606386822804754362408956522921410859852037330544625953261340234864689275060526893755148403298542086991221052597005628576707702567695300978970046408920009852106980295419699802138053295798159478289934443245491565327845223840551240445208226435420656313310702940722371552770504263482073984454889589248861397657079145414427653584572951329719091947694411910966797474262675590953832039169673494261360032263077428684105040061351052194413778158095005714526846009810352109249040027958050736436961021241137739717164869525493114805040126568351268829598413983222676377804500626507241731757395219796890754825199329259649801627068665658030178877405615167159731927320479376247375505855052839660294566992522173600874081212014209071041937598571721431338017425141582491824710905084715977249417049320254165239323233258851588893337097136310892571531417761978326033750109026284066415801371359356529278088456305951770081443994114674291850360748852366654744869928083230516815711602911836374147958492100860528981469547750812338896943152861021202736747049903930417035171342126923486700566627506229058636911882228903170510305406882096970875545329369434063981297696478031825451642178347347716471058423238594580183052756213910186997604305844068665712346869679456044155742100039179758348979935882751881524675930878928159243492197545387668305684668420775409821781247053354523194797398953320175988640281058825557698004397120538312459428957377696001857497335249965013509368925958021863811725906506436882127156815751021712900765992750370228283963962915973251173418586721023497317765969454283625519371556009143680329311962842546628403142444370648432390374906410811300792848955767243481200090309888457270907750873638873299642555050473812528975962934822878917619920725138309388288292510416837622758204081918933603653875284116785703720989718832986921927816629675844580174911809119663048187434155067790863948831489241504300476704527971283482211522202837062857314244107823792513645086677566622804977211397140621664116324756784216612961477109018826094677377686406176721484293894976671380122788941309026553511096118347012565197540807095384060916863936906673786627209429434264260402902158317345003727462588992622049877121178405563348492490326003508569099382392777297498413565614830788262363322368380709822346012274241379036473451735925215754757160934270935192901723954921426490691115271523338109124042812102893738488167358953934508930697715522989199698903885883275409044300321986834003470271220020159699371690650330547577095398748580670024491045504890061727189168031394528036165633941571334637222550477547460756055024108764382121688848916940371258901948490685379722244562009483819491532724502276218589169507405794983759821006604481996519360110261576947176202571702048684914616894068404140833587562118319210838005632144562018941505945780025318747471911604840677997765414830622179069330853875129298983009580277554145435058768984944179136535891620098725222049055183554603706533183176716110738009786625247488691476077664470147193074476302411660335671765564874440577990531996271632972009109449249216456030618827772947750764777446452586328919159107444252320082918209518021083700353881330983215894608680127954224752071924134648334963915094813097541433244209299930751481077919002346128122330161799429930618800533414550633932139339646861616416955220216447995417243171165744471364197733204899365074767844149929548073025856442942381787641506492878361767978677158510784235702640213388018875601989234056868423215585628508645525258377010620532224244987990625263484010774322488172558602233302076399933854152015343847725442917895130637050320444917797752370871958277976799686113626532291118629631164685159934660693460557545956063155830033697634000276685151293843638886090828376141157732003527565158745906567025439437931104838571313294490604926582363108949535090082673154497226396648088618041573977888472892174618974189721700770009862449653759012727015227634510874906948012210684952063002519011655963580552429180205586904259685261047412834518466736938580027700252965356366721619883672428226933950325930390994583168665542234654857020875504617520521853721567282679903418135520602999895366470106557900532129541336924472492212436324523042895188461779122338069674233980694887270587503389228395095135209123109258159006960395156367736067109050566299603571876423247920752836160805597697778756476767210521222327184821484446631261487584226092608875764331731023263768864822594691211032367737558122133470556805958008310127481673962019583598023967414489867276845869819376783757167936723213081586191045995058970991064686919463448038574143829629547131372173669836184558144505748676124322451519943362182916191468026091121793001864788050061351603144350076189213441602488091741051232290357179205497927970924502479940842696158818442616163780044759478212240873204124421169199805572649118243661921835714762891425805771871743688000324113008704819373962295017143090098476927237498875938639942530595331607891618810863505982444578942799346514915952884869757488025823353571677864826828051140885429732788197765736966005727700162592404301688659946862983717270595809808730901820120931003430058796552694788049809205484305467611034654748067290674399763612592434637719995843862812391985470202414880076880818848087892391591369463293113276849329777201646641727587259122354784480813433328050087758855264686119576962172239308693795757165821852416204341972383989932734803429262340722338155102209101262949249742423271698842023297303260161790575673111235465890298298313115123607606773968998153812286999642014609852579793691246016346088762321286205634215901479188632194659637483482564291616278532948239313229440231043277288768139550213348266388687453259281587854503890991561949632478855035090289390973718988003999026132015872678637873095678109625311008054489418857983565902063680699643165033912029944327726770869305240718416592070096139286401966725750087012218149733133695809600369751764951350040285926249203398111014953227533621844500744331562434532484217986108346261345897591234839970751854223281677187215956827243245910829019886390369784542622566912542747056097567984857136623679023878478161201477982939080513150258174523773529510165296934562786122241150783587755373348372764439838082000667214740034466322776918936967612878983488942094688102308427036452854504966759697318836044496702853190637396916357980928865719935397723495486787180416401415281489443785036291071517805285857583987711145474240156416477194116391354935466755593592608849200546384685403028080936417250583653368093407225310820844723570226809826951426162451204040711501448747856199922814664565893938488028643822313849852328452360667045805113679663751039248163336173274547275775636810977344539275827560597425160705468689657794530521602315939865780974801515414987097778078705357058008472376892422189750312758527140173117621279898744958406199843913365680297721208751934988504499713914285158032324823021340630312586072624541637765234505522051086318285359658520708173392709566445011404055106579055037417780393351658360904543047721422281816832539613634982525215232257690920254216409657452618066051777901592902884240599998882753691957540116954696152270401280857579766154722192925655963991820948894642657512288766330302133746367449217449351637104725732980832812726468187759356584218383594702792013663907689741738962252575782663990809792647011407580367850599381887184560094695833270775126181282015391041773950918244137561999937819240362469558235924171478702779448443108751901807414110290370706052085162975798361754251041642244867577350756338018895379263183389855955956527857227926155524494739363665533904528656215464288343162282921123290451842212532888101415884061619939195042230059898349966569463580186816717074818823215848647734386780911564660755175385552224428524049468033692299989300783900020690121517740696428573930196910500988278523053797637940257968953295112436166778910585557213381789089945453947915927374958600268237844486872037243488834616856290097850532497036933361942439802882364323553808208003875741710969289725499878566253048867033095150518452126944989251596392079421452606508516052325614861938282489838000815085351564642761700832096483117944401971780149213345335903336672376719229722069970766055482452247416927774637522135201716231722137632445699154022395494158227418930589911746931773776518735850032318014432883916374243795854695691221774098948611515564046609565094538115520921863711518684562543275047870530006998423140180169421109105925493596116719457630962328831271268328501760321771680400249657674186927113215573270049935709942324416387089242427584407651215572676037924765341808984312676941110313165951429479377670698881249643421933287404390485538222160837088907598277390184204138197811025854537088586701450623578513960109987476052535450100439353062072439709976445146790993381448994644609780957731953604938734950026860564555693224229691815630293922487606470873431166384205442489628760213650246991893040112513103835085621908060270866604873585849001704200923929789193938125116798421788115209259130435572321635660895603514383883939018953166274355609970015699780289236362349895374653428746875

Şimdi uyguladığım başka bir yaklaşım ise Bölme ve Eşleştirme yoluyla yineleme yoluyla

yani Fib (n) = fib (n-1) + Fib (n-2) ve daha sonra n-1 & n-2 için tekrar tekrar ..... 2 & 1'e kadar - olarak programlanır

package com.company.dynamicProgramming;

import java.math.BigInteger;

public class FibonacciByBigDecimal {

    public static void main(String ...args) {

        int n = 100000;
        BigInteger[] fibOfnS = new BigInteger[n + 1];

        System.out.println("fibonacci of "+ n + " is : " + fibByDivCon(n, fibOfnS));

    }


    static BigInteger fibByDivCon(int n, BigInteger[] fibOfnS){

        if(fibOfnS[n]!=null){
            return fibOfnS[n];
        }

        if (n == 1 || n== 2){
            fibOfnS[n] = BigInteger.ONE;
            return BigInteger.ONE;
        }

        // creates 2 further entries in stack
        BigInteger fibOfn = fibByDivCon(n-1, fibOfnS).add( fibByDivCon(n-2, fibOfnS)) ;

        fibOfnS[n] = fibOfn;

        return fibOfn;

    }

}

Kodu n = 100.000 için çalıştırdığımda sonuç aşağıdaki gibidir -

Exception in thread "main" java.lang.StackOverflowError
    at com.company.dynamicProgramming.FibonacciByBigDecimal.fibByDivCon(FibonacciByBigDecimal.java:29)
    at com.company.dynamicProgramming.FibonacciByBigDecimal.fibByDivCon(FibonacciByBigDecimal.java:29)
    at com.company.dynamicProgramming.FibonacciByBigDecimal.fibByDivCon(FibonacciByBigDecimal.java:29)

Yukarıda StackOverflowError'ın oluşturulduğunu görebilirsiniz. Şimdi bunun nedeni çok fazla özyinelemedir -

        // creates 2 further entries in stack
        BigInteger fibOfn = fibByDivCon(n-1, fibOfnS).add( fibByDivCon(n-2, fibOfnS)) ;

Yani yığındaki her girdi 2 girdi daha oluşturur ve bu böyle devam eder ...

görüntü açıklamasını buraya girin

Sonunda, sistemin yığında işleyemeyeceği kadar çok girdi oluşturulur ve StackOverflowError atılır.

Önleme için: Yukarıdaki örnek perspektif için - 1. Özyineleme yaklaşımını kullanmaktan kaçının veya özyinelemeyi, n çok büyükse olduğu gibi bir düzey bölmeyle azaltın / sınırlayın, sonra sistemin kendi sınırıyla başa çıkabilmesi için n'yi bölün. 2. 1. kod örneğinde kullandığım döngü yaklaşımı gibi diğer yaklaşımı kullanın. (Pek çok ünlü algoritmada efsanevi yaklaşımlar oldukları için Bölme ve Eşleştirme veya Özyinelemeyi indirgemeyi amaçlamıyorum. Niyetim yığın taşması sorunlarından şüpheleniyorsam özyinelemeyi sınırlamak veya yinelemeden uzak durmaktır)

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.