Làm thế nào để xảy ra "tràn ngăn xếp" và làm cách nào để ngăn chặn nó?


97

Làm thế nào để xảy ra tràn ngăn xếp và đâu là cách tốt nhất để đảm bảo nó không xảy ra hoặc các cách ngăn chặn, đặc biệt là trên máy chủ web, nhưng các ví dụ khác cũng sẽ thú vị?

Câu trả lời:


126

Cây rơm

Một ngăn xếp, trong ngữ cảnh này, là bộ đệm cuối cùng trong, đầu tiên mà bạn đặt dữ liệu trong khi chương trình của bạn chạy. Cuối cùng, xuất trước (LIFO) có nghĩa là thứ cuối cùng bạn đưa vào luôn là thứ đầu tiên bạn lấy ra - nếu bạn đẩy 2 mục trên ngăn xếp, 'A' và sau đó là 'B', thì thứ đầu tiên bạn bật ra ra khỏi ngăn xếp sẽ là 'B', và điều tiếp theo là 'A'.

Khi bạn gọi một hàm trong mã của mình, lệnh tiếp theo sau lệnh gọi hàm được lưu trữ trên ngăn xếp và mọi không gian lưu trữ có thể bị ghi đè bởi lệnh gọi hàm. Hàm bạn gọi có thể sử dụng nhiều ngăn xếp hơn cho các biến cục bộ của chính nó. Khi hoàn tất, nó giải phóng không gian ngăn xếp biến cục bộ mà nó đã sử dụng, sau đó quay lại hàm trước đó.

Tràn ngăn xếp

Tràn ngăn xếp là khi bạn đã sử dụng nhiều bộ nhớ cho ngăn xếp hơn chương trình của bạn được cho là sử dụng. Trong hệ thống nhúng, bạn có thể chỉ có 256 byte cho ngăn xếp và nếu mỗi hàm chiếm 32 byte thì bạn chỉ có thể có các lệnh gọi hàm 8 sâu - hàm 1 gọi hàm 2 ai gọi hàm 3 ai gọi hàm 4 .... ai gọi hàm 8 gọi hàm 9, nhưng hàm 9 ghi đè bộ nhớ bên ngoài ngăn xếp. Điều này có thể ghi đè bộ nhớ, mã, v.v.

Nhiều lập trình viên mắc lỗi này khi gọi hàm A rồi gọi hàm B, sau đó gọi hàm C, rồi gọi hàm A. Nó có thể hoạt động hầu hết thời gian, nhưng chỉ cần một lần nhập sai sẽ khiến nó đi trong vòng tròn đó mãi mãi. cho đến khi máy tính nhận ra rằng ngăn xếp bị thổi phồng quá mức.

Các hàm đệ quy cũng là một nguyên nhân gây ra điều này, nhưng nếu bạn đang viết đệ quy (tức là hàm của bạn tự gọi) thì bạn cần lưu ý điều này và sử dụng các biến tĩnh / toàn cục để ngăn chặn đệ quy vô hạn.

Nói chung, hệ điều hành và ngôn ngữ lập trình bạn đang sử dụng quản lý ngăn xếp và nó nằm ngoài tầm tay của bạn. Bạn nên xem biểu đồ cuộc gọi của mình (một cấu trúc cây hiển thị từ chính của bạn những gì mà mỗi hàm gọi) để xem mức độ sâu của các lệnh gọi hàm của bạn và để phát hiện các chu kỳ và đệ quy không được dự định. Chu kỳ có chủ ý và đệ quy cần được kiểm tra giả tạo để tìm ra lỗi nếu chúng gọi nhau quá nhiều lần.

Ngoài các phương pháp lập trình tốt, thử nghiệm tĩnh và động, bạn không thể làm gì nhiều trên các hệ thống cấp cao này.

Những hệ thống nhúng

Trong thế giới nhúng, đặc biệt là trong mã có độ tin cậy cao (ô tô, máy bay, vũ trụ), bạn thực hiện đánh giá và kiểm tra mã rộng rãi, nhưng bạn cũng làm như sau:

  • Không cho phép đệ quy và chu trình - được thực thi bởi chính sách và thử nghiệm
  • Giữ mã và ngăn xếp cách xa nhau (mã trong flash, ngăn xếp trong RAM và không bao giờ hai mã gặp nhau)
  • Đặt các dải bảo vệ xung quanh ngăn xếp - vùng trống của bộ nhớ mà bạn lấp đầy bằng một số ma thuật (thường là hướng dẫn ngắt phần mềm, nhưng có nhiều tùy chọn ở đây) và hàng trăm hoặc hàng nghìn lần mỗi giây bạn nhìn vào các dải bảo vệ để đảm bảo chúng không bị ghi đè.
  • Sử dụng bảo vệ bộ nhớ (nghĩa là không thực thi trên ngăn xếp, không đọc hoặc ghi ngay bên ngoài ngăn xếp)
  • Ngắt không gọi các chức năng phụ - chúng đặt cờ, sao chép dữ liệu và để ứng dụng xử lý nó (nếu không, bạn có thể nhận được 8 sâu trong cây gọi hàm của mình, có một ngắt và sau đó loại bỏ một vài hàm khác bên trong làm gián đoạn, gây ra sự cố). Bạn có một số cây cuộc gọi - một cây cho các quy trình chính và một cây cho mỗi ngắt. Nếu các ngắt của bạn có thể làm gián đoạn lẫn nhau ... tốt, có những con rồng ...

Ngôn ngữ và hệ thống cấp cao

Nhưng ở các ngôn ngữ cấp cao chạy trên hệ điều hành:

  • Giảm lưu trữ biến cục bộ của bạn (các biến cục bộ được lưu trữ trên ngăn xếp - mặc dù các trình biên dịch khá thông minh về điều này và đôi khi sẽ đặt các biến cục bộ lớn trên đống nếu cây gọi của bạn nông)
  • Tránh hoặc hạn chế triệt để đệ quy
  • Đừng chia nhỏ chương trình của bạn thành các hàm nhỏ hơn và nhỏ hơn - ngay cả khi không tính các biến cục bộ, mỗi lệnh gọi hàm sẽ tiêu thụ tối đa 64 byte trên ngăn xếp (bộ xử lý 32 bit, tiết kiệm một nửa thanh ghi CPU, cờ, v.v.)
  • Giữ cây cuộc gọi của bạn nông (tương tự như câu lệnh trên)

Máy chủ web

Nó phụ thuộc vào 'hộp cát' mà bạn có, liệu bạn có thể kiểm soát hoặc thậm chí nhìn thấy ngăn xếp hay không. Rất có thể bạn có thể xử lý các máy chủ web như với bất kỳ hệ điều hành và ngôn ngữ cấp cao nào khác - nó chủ yếu nằm ngoài tầm tay của bạn, nhưng hãy kiểm tra ngôn ngữ và ngăn xếp máy chủ bạn đang sử dụng. Nó tốt để thổi ngăn xếp trên máy chủ SQL của bạn, ví dụ.

-Adam


8

Rất hiếm khi xảy ra tràn ngăn xếp trong mã thực. Hầu hết các tình huống mà nó xảy ra là đệ quy trong đó phần kết thúc đã bị quên. Tuy nhiên, nó có thể hiếm khi xảy ra trong các cấu trúc có tính lồng ghép cao, ví dụ như các tài liệu XML đặc biệt lớn. Sự trợ giúp thực sự duy nhất ở đây là cấu trúc lại mã để sử dụng một đối tượng ngăn xếp rõ ràng thay vì ngăn xếp cuộc gọi.


7

Hầu hết mọi người sẽ cho bạn biết rằng tràn ngăn xếp xảy ra với đệ quy mà không có đường thoát - trong khi hầu hết đúng, nếu bạn làm việc với cấu trúc dữ liệu đủ lớn, thì ngay cả một đường thoát đệ quy thích hợp cũng không giúp được gì cho bạn.

Một số tùy chọn trong trường hợp này:


7

Sự cố tràn ngăn xếp xảy ra khi Jeff và Joel muốn mang đến cho thế giới một nơi tốt hơn để nhận câu trả lời cho các câu hỏi kỹ thuật. Đã quá muộn để ngăn chặn tràn ngăn xếp này. "Trang web khác" đó có thể đã ngăn chặn nó bằng cách không bịp bợm. ;)


6

Đệ quy vô hạn là một cách phổ biến để gặp lỗi tràn ngăn xếp. Để ngăn chặn - hãy luôn đảm bảo rằng có một lối thoát sẽ bị đánh. :-)

Một cách khác để tránh tràn ngăn xếp (ít nhất là trong C / C ++) là khai báo một số biến khổng lồ trên ngăn xếp.

char hugeArray[100000000];

Điều đó sẽ làm được.


Ngôn ngữ của bạn đang sử dụng là gì? Trong C, điều này gần như chắc chắn sẽ dẫn đến tràn ngăn xếp. Trong C #, nó sẽ không xảy ra vì mảng được phân bổ trên heap chứ không phải trên stack. Hãy xem câu hỏi này để biết ví dụ về điều này đang được thực hiện trong thực tế: stackoverflow.com/questions/571945/…
Matt Dillard

4

Thông thường, tràn ngăn xếp là kết quả của một lệnh gọi đệ quy vô hạn (với lượng bộ nhớ thông thường trong các máy tính tiêu chuẩn hiện nay).

Khi bạn thực hiện cuộc gọi đến một phương thức, hàm hoặc thủ tục theo cách "chuẩn" hoặc thực hiện cuộc gọi bao gồm:

  1. Đẩy hướng trả về cho cuộc gọi vào ngăn xếp (đó là câu tiếp theo sau cuộc gọi)
  2. Thông thường không gian cho giá trị trả về được dành riêng vào ngăn xếp
  3. Đẩy từng tham số vào ngăn xếp (thứ tự phân kỳ và phụ thuộc vào từng trình biên dịch, một số trong số chúng đôi khi được lưu trữ trên thanh ghi CPU để cải thiện hiệu suất)
  4. Thực hiện cuộc gọi thực tế.

Vì vậy, điều này thường mất một vài byte phụ thuộc vào số lượng và kiểu của các tham số cũng như kiến ​​trúc máy.

Sau đó, bạn sẽ thấy rằng nếu bạn bắt đầu thực hiện các cuộc gọi đệ quy, ngăn xếp sẽ bắt đầu phát triển. Bây giờ, ngăn xếp thường được dự trữ trong bộ nhớ theo cách mà nó phát triển theo hướng ngược lại với đống, do một số lượng lớn lệnh gọi mà không cần "quay lại" ngăn xếp bắt đầu đầy.

Bây giờ, vào thời gian cũ hơn, tràn ngăn xếp có thể xảy ra đơn giản vì bạn đã sử dụng hết bộ nhớ có sẵn, giống như vậy. Với mô hình bộ nhớ ảo (lên đến 4GB trên hệ thống X86) nằm ngoài phạm vi nên thông thường, nếu bạn gặp lỗi tràn ngăn xếp, hãy tìm một lệnh gọi đệ quy vô hạn.


4

Gì? Không ai có tình yêu với những người được bao bọc bởi một vòng lặp vô hạn?

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

2
Đây là một vòng lặp vô hạn, không phải là tràn ngăn xếp
Eddie Curtis

3

Ngoài dạng tràn ngăn xếp mà bạn nhận được từ đệ quy trực tiếp (ví dụ Fibonacci(1000000):), một dạng khác tinh vi hơn mà tôi đã trải qua nhiều lần là đệ quy gián tiếp, trong đó một hàm gọi một hàm khác, hàm này gọi một hàm khác, và sau đó là một trong các các hàm đó lại gọi hàm đầu tiên.

Điều này có thể thường xảy ra trong các hàm được gọi để đáp ứng với các sự kiện nhưng bản thân chúng có thể tạo ra các sự kiện mới, ví dụ:

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

Trong trường hợp này, lệnh gọi tới ResizeWindowcó thể khiến lệnh WindowSizeChanged()gọi lại được kích hoạt trở lại, lệnh gọi ResizeWindowlại sẽ gọi lại, cho đến khi bạn hết ngăn xếp. Trong những tình huống như thế này, bạn thường cần trì hoãn phản hồi sự kiện cho đến khi khung ngăn xếp đã quay trở lại, ví dụ bằng cách đăng một tin nhắn.


2

Xem xét điều này được gắn thẻ "hack", tôi nghi ngờ "tràn ngăn xếp" mà anh ấy đang đề cập là tràn ngăn xếp cuộc gọi, chứ không phải tràn ngăn xếp cấp cao hơn như được tham chiếu trong hầu hết các câu trả lời khác ở đây. Nó không thực sự áp dụng cho bất kỳ môi trường được quản lý hoặc thông dịch nào như .NET, Java, Python, Perl, PHP, v.v., những ứng dụng web thường được viết bằng, vì vậy rủi ro duy nhất của bạn là chính máy chủ web, có thể được viết bằng C hoặc C ++.

Kiểm tra chủ đề này:

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


1

Tôi đã tạo lại sự cố tràn ngăn xếp trong khi nhận được số Fibonacci phổ biến nhất, tức là 1, 1, 2, 3, 5 ..... vì vậy, phép tính cho fib (1) = 1 hoặc fib (3) = 2 .. fib (n ) = ??.

đối với n, giả sử chúng ta sẽ quan tâm - nếu n = 100.000 thì số Fibonacci tương ứng sẽ như thế nào ??

Cách tiếp cận một vòng lặp như sau:

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;
    }

}

điều này khá dễ hiểu và kết quả là -

fibonacci of 100000 is : 2597406934722172416615503402127591541488048538651769658472477070395253454351127368626555677283671674475463758722307443211163839947387509103096569738218830449305228763853133492135302679278956701051276578271635608073050532200243233114383986516137827238124777453778337299916214634050054669860390862750996639366409211890125271960172105060300350586894028558103675117658251368377438684936413457338834365158775425371912410500332195991330062204363035213756525421823998690848556374080179251761629391754963458558616300762819916081109836526352995440694284206571046044903805647136346033000520852277707554446794723709030979019014860432846819857961015951001850608264919234587313399150133919932363102301864172536477136266475080133982431231703431452964181790051187957316766834979901682011849907756686456845066287392485603914047605199550066288826345877189410680370091879365001733011710028310473947456256091444932821374855573864080579813028266640270354294412104919995803131876805899186513425175959911520563155337703996941035518275274919959802257507902037798103089922984996304496255814045517000250299764322193462165366210841876745428298261398234478366581588040819003307382939500082132009374715485131027220817305432264866949630987914714362925554252624043999615326979876807510646819068792118299167964409178271868561702918102212679267401362650499784968843680975254700131004574186406448299485872551744746695651879126916993244564817673322257149314967763345846623830333820239702436859478287641875788572910710133700300094229333597292779191409212804901545976262791057055248158884051779418192905216769576608748815567860128818354354292307397810154785701328438612728620176653953444993001980062953893698550072328665131718113588661353747268458543254898113717660519461693791688442534259478126310388952047956594380715301911253964847112638900713362856910155145342332944128435722099628674611942095166100230974070996553190050815866991144544264788287264284501725332048648319457892039984893823636745618220375097348566847433887249049337031633826571760729778891798913667325190623247118037280173921572390822769228077292456662750538337500692607721059361942126892030256744356537800831830637593334502350256972906515285327194367756015666039916404882563967693079290502951488693413799125174856667074717514938979038653338139534684837808612673755438382110844897653836848318258836339917310455850905663846202501463131183108742907729262215943020429159474030610183981685506695026197376150857176119947587572212987205312060791864980361596092339594104118635168854883911918517906151156275293615849000872150192226511785315089251027528045151238603792184692121533829287136924321527332714157478829590260157195485316444794546750285840236000238344790520345108033282013803880708980734832620122795263360677366987578332625485944906021917368867786241120562109836985019729017715780112040458649153935115783499546100636635745448508241888279067531359950519206222976015376529797308588164873117308237059828489404487403932053592935976454165560795472477862029969232956138971989467942218727360512336559521133108778758228879597580320459608479024506385194174312616377510459921102486879496341706862092908893068525234805692599833377510390101316617812305114571932706629167125446512151746802548190358351688971707570677865618800822034683632101813026232996027599403579997774046244952114531588370357904483293150007246173417355805567832153454341170020258560809166294198637401514569572272836921963229511187762530753402594781448204657460288485500062806934811398276016855584079542162057543557291510641537592939022884356120792643705560062367986544382464373946972471945996555795505838034825597839682776084731530251788951718630722761103630509360074262261717363058613291544024695432904616258691774630578507674937487992329181750163484068813465534370997589353607405172909412697657593295156818624747127636468836551757018353417274662607306510451195762866349922848678780591085118985653555434958761664016447588028633629704046289097067736256584300235314749461233912068632146637087844699210427541569410912246568571204717241133378489816764096924981633421176857150311671040068175303192115415611958042570658693127276213710697472226029655524611053715554532499750843275200199214301910505362996007042963297805103066650638786268157658772683745128976850796366371059380911225428835839194121154773759981301921650952140133306070987313732926518169226845063443954056729812031546392324981793780469103793422169495229100793029949237507299325063050942813902793084134473061411643355614764093104425918481363930542369378976520526456347648318272633371512112030629233889286487949209737847861884868260804647319539200840398308008803869049557419756219293922110825766397681361044490024720948340326796768837621396744075713887292863079821849314343879778088737958896840946143415927131757836511457828935581859902923534388888846587452130838137779443636119762839036894595760120316502279857901545344747352706972851454599861422902737291131463782045516225447535356773622793648545035710208644541208984235038908770223039849380214734809687433336225449150117411751570704561050895274000206380497967960402617818664481248547269630823473377245543390519841308769781276565916764229022948181763075710255793365008152286383634493138089971785087070863632205869018938377766063006066757732427272929247421295265000706646722730009956124191409138984675224955790729398495608750456694217771551107346630456603944136235888443676215273928597072287937355966723924613827468703217858459948257514745406436460997059316120596841560473234396652457231650317792833860590388360417691428732735703986803342604670071717363573091122981306903286137122597937096605775172964528263757434075792282180744352908669606854021718597891166333863858589736209114248432178645039479195424208191626088571069110433994801473013100869848866430721216762473119618190737820766582968280796079482259549036328266578006994856825300536436674822534603705134503603152154296943991866236857638062351209884448741138600171173647632126029961408561925599707566827866778732377419444462275399909291044697716476151118672327238679208133367306181944849396607123345271856520253643621964198782752978813060080313141817069314468221189275784978281094367751540710106350553798003842219045508482239386993296926659221112742698133062300073465628498093636693049446801628553712633412620378491919498600097200836727876650786886306933418995225768314390832484886340318940194161036979843833346608676709431643653538430912157815543512852077720858098902099586449602479491970687230765687109234380719509824814473157813780080639358418756655098501321882852840184981407690738507369535377711880388528935347600930338598691608289335421147722936561907276264603726027239320991187820407067412272258120766729040071924237930330972132364184093956102995971291799828290009539147382437802779051112030954582532888721146170133440385939654047806199333224547317803407340902512130217279595753863158148810392952475410943880555098382627633127606718126171022011356181800775400227516734144169216424973175621363128588281978005788832454534581522434937268133433997710512532081478345067139835038332901313945986481820272322043341930929011907832896569222878337497354301561722829115627329468814853281922100752373626827643152685735493223028018101449649009015529248638338885664893002250974343601200814365153625369199446709711126951966725780061891215440222487564601554632812091945824653557432047644212650790655208208337976071465127508320487165271577472325887275761128357592132553934446289433258105028633583669291828566894736223508250294964065798630809614341696830467595174355313224362664207197608459024263017473392225291248366316428006552870975051997504913009859468071013602336440164400179188610853230764991714372054467823597211760465153200163085336319351589645890681722372812310320271897917951272799656053694032111242846590994556380215461316106267521633805664394318881268199494005537068697621855231858921100963441012933535733918459668197539834284696822889460076352031688922002021931318369757556962061115774305826305535862015637891246031220672933992617378379625150999935403648731423208873977968908908369996292995391977217796533421249291978383751460062054967341662833487341011097770535898066498136011395571584328308713940582535274056081011503907941688079197212933148303072638678631411038443128215994936824342998188719768637604496342597524256886188688978980888315865076262604856465004322896856149255063968811404400429503894245872382233543101078691517328333604779262727765686076177705616874050257743749983775830143856135427273838589774133526949165483929721519554793578923866762502745370104660909382449626626935321303744538892479216161188889702077910448563199514826630802879549546453583866307344423753319712279158861707289652090149848305435983200771326653407290662016775706409690183771201306823245333477966660525325490873601961480378241566071271650383582257289215708209369510995890132859490724306183325755201208090007175022022949742801823445413711916298449914722254196594682221468260644961839254249670903104007581488857971672246322887016438403908463856731164308169537326790303114583680575021119639905615169154708510459700542098571797318015564741406172334145847111268547929892443001391468289103679179216978616582489007322033591376706527676521307143985302760988478056216994659655461379174985659739227379416726495377801992098355427866179123126699374730777730569324430166839333011554515542656864937492128687049121754245967831132969248492466744261999033972825674873460201150442228780466124320183016108232183908654771042398228531316559685688005226571474428823317539456543881928624432662503345388199590085105211383124491861802624432195540433985722841341254409411771722156867086291742124053110620522842986199273629406208834754853645128123279609097213953775360023076765694208219943034648783348544492713539450224591334374664937701655605763384697062918725745426505879414630176639760457474311081556747091652708748125267159913793240527304613693961169892589808311906322510777928562071999459487700611801002296132304588294558440952496611158342804908643860880796440557763691857743754025896855927252514563404385217825890599553954627451385454452916761042969267970893580056234501918571489030418495767400819359973218711957496357095967825171096264752068890806407651445893132870767454169607107931692704285168093413311046353506242209810363216771910420786162184213763938194625697286781413636389620123976910465418956806197323148414224550071617215851321302030684176087215892702098879108938081045903397276547326416916845445627600759561367103584575649094430692452532085003091068783157561519847567569191284784654692558665111557913461272425336083635131342183905177154511228464455136016013513228948543271504760839307556100908786096663870612278690274831819331606701484957163004705262228238406266818448788374548131994380387613830128859885264201992286188208499588640888521352501457615396482647451025902530743172956899636499615707551855837165935367125448515089362904567736630035562457374779100987992499146967224041481601289530944015488942613783140087804311431741858071826185149051138744831358439067228949408258286021650288927228387426432786168690381960530155894459451808735197246008221529343980828254126128257157209350985382800738560472910941184006084485235377833503306861977724501886364070344973366473100602018128792886991861824418453968994777259482169137133647470453172979809245844361129618997595696240971845564020511432589591844724920942930301651488713079802102379065536525154780298059407529440513145807551537794861635879901158192019808879694967187448224156836463534326160242632934761634458163890163805123894184523973421841496889262398489648642093409816681494771155177009562669029850101513537599801272501241971119871526593747484778935488777815192931171431167444773882941064615028751327709474504763922874890662989841540259350834035142035136168819248238998027706666916342133424312054507359388616687691188185776118135771332483965209882085982391298606386822804754362408956522921410859852037330544625953261340234864689275060526893755148403298542086991221052597005628576707702567695300978970046408920009852106980295419699802138053295798159478289934443245491565327845223840551240445208226435420656313310702940722371552770504263482073984454889589248861397657079145414427653584572951329719091947694411910966797474262675590953832039169673494261360032263077428684105040061351052194413778158095005714526846009810352109249040027958050736436961021241137739717164869525493114805040126568351268829598413983222676377804500626507241731757395219796890754825199329259649801627068665658030178877405615167159731927320479376247375505855052839660294566992522173600874081212014209071041937598571721431338017425141582491824710905084715977249417049320254165239323233258851588893337097136310892571531417761978326033750109026284066415801371359356529278088456305951770081443994114674291850360748852366654744869928083230516815711602911836374147958492100860528981469547750812338896943152861021202736747049903930417035171342126923486700566627506229058636911882228903170510305406882096970875545329369434063981297696478031825451642178347347716471058423238594580183052756213910186997604305844068665712346869679456044155742100039179758348979935882751881524675930878928159243492197545387668305684668420775409821781247053354523194797398953320175988640281058825557698004397120538312459428957377696001857497335249965013509368925958021863811725906506436882127156815751021712900765992750370228283963962915973251173418586721023497317765969454283625519371556009143680329311962842546628403142444370648432390374906410811300792848955767243481200090309888457270907750873638873299642555050473812528975962934822878917619920725138309388288292510416837622758204081918933603653875284116785703720989718832986921927816629675844580174911809119663048187434155067790863948831489241504300476704527971283482211522202837062857314244107823792513645086677566622804977211397140621664116324756784216612961477109018826094677377686406176721484293894976671380122788941309026553511096118347012565197540807095384060916863936906673786627209429434264260402902158317345003727462588992622049877121178405563348492490326003508569099382392777297498413565614830788262363322368380709822346012274241379036473451735925215754757160934270935192901723954921426490691115271523338109124042812102893738488167358953934508930697715522989199698903885883275409044300321986834003470271220020159699371690650330547577095398748580670024491045504890061727189168031394528036165633941571334637222550477547460756055024108764382121688848916940371258901948490685379722244562009483819491532724502276218589169507405794983759821006604481996519360110261576947176202571702048684914616894068404140833587562118319210838005632144562018941505945780025318747471911604840677997765414830622179069330853875129298983009580277554145435058768984944179136535891620098725222049055183554603706533183176716110738009786625247488691476077664470147193074476302411660335671765564874440577990531996271632972009109449249216456030618827772947750764777446452586328919159107444252320082918209518021083700353881330983215894608680127954224752071924134648334963915094813097541433244209299930751481077919002346128122330161799429930618800533414550633932139339646861616416955220216447995417243171165744471364197733204899365074767844149929548073025856442942381787641506492878361767978677158510784235702640213388018875601989234056868423215585628508645525258377010620532224244987990625263484010774322488172558602233302076399933854152015343847725442917895130637050320444917797752370871958277976799686113626532291118629631164685159934660693460557545956063155830033697634000276685151293843638886090828376141157732003527565158745906567025439437931104838571313294490604926582363108949535090082673154497226396648088618041573977888472892174618974189721700770009862449653759012727015227634510874906948012210684952063002519011655963580552429180205586904259685261047412834518466736938580027700252965356366721619883672428226933950325930390994583168665542234654857020875504617520521853721567282679903418135520602999895366470106557900532129541336924472492212436324523042895188461779122338069674233980694887270587503389228395095135209123109258159006960395156367736067109050566299603571876423247920752836160805597697778756476767210521222327184821484446631261487584226092608875764331731023263768864822594691211032367737558122133470556805958008310127481673962019583598023967414489867276845869819376783757167936723213081586191045995058970991064686919463448038574143829629547131372173669836184558144505748676124322451519943362182916191468026091121793001864788050061351603144350076189213441602488091741051232290357179205497927970924502479940842696158818442616163780044759478212240873204124421169199805572649118243661921835714762891425805771871743688000324113008704819373962295017143090098476927237498875938639942530595331607891618810863505982444578942799346514915952884869757488025823353571677864826828051140885429732788197765736966005727700162592404301688659946862983717270595809808730901820120931003430058796552694788049809205484305467611034654748067290674399763612592434637719995843862812391985470202414880076880818848087892391591369463293113276849329777201646641727587259122354784480813433328050087758855264686119576962172239308693795757165821852416204341972383989932734803429262340722338155102209101262949249742423271698842023297303260161790575673111235465890298298313115123607606773968998153812286999642014609852579793691246016346088762321286205634215901479188632194659637483482564291616278532948239313229440231043277288768139550213348266388687453259281587854503890991561949632478855035090289390973718988003999026132015872678637873095678109625311008054489418857983565902063680699643165033912029944327726770869305240718416592070096139286401966725750087012218149733133695809600369751764951350040285926249203398111014953227533621844500744331562434532484217986108346261345897591234839970751854223281677187215956827243245910829019886390369784542622566912542747056097567984857136623679023878478161201477982939080513150258174523773529510165296934562786122241150783587755373348372764439838082000667214740034466322776918936967612878983488942094688102308427036452854504966759697318836044496702853190637396916357980928865719935397723495486787180416401415281489443785036291071517805285857583987711145474240156416477194116391354935466755593592608849200546384685403028080936417250583653368093407225310820844723570226809826951426162451204040711501448747856199922814664565893938488028643822313849852328452360667045805113679663751039248163336173274547275775636810977344539275827560597425160705468689657794530521602315939865780974801515414987097778078705357058008472376892422189750312758527140173117621279898744958406199843913365680297721208751934988504499713914285158032324823021340630312586072624541637765234505522051086318285359658520708173392709566445011404055106579055037417780393351658360904543047721422281816832539613634982525215232257690920254216409657452618066051777901592902884240599998882753691957540116954696152270401280857579766154722192925655963991820948894642657512288766330302133746367449217449351637104725732980832812726468187759356584218383594702792013663907689741738962252575782663990809792647011407580367850599381887184560094695833270775126181282015391041773950918244137561999937819240362469558235924171478702779448443108751901807414110290370706052085162975798361754251041642244867577350756338018895379263183389855955956527857227926155524494739363665533904528656215464288343162282921123290451842212532888101415884061619939195042230059898349966569463580186816717074818823215848647734386780911564660755175385552224428524049468033692299989300783900020690121517740696428573930196910500988278523053797637940257968953295112436166778910585557213381789089945453947915927374958600268237844486872037243488834616856290097850532497036933361942439802882364323553808208003875741710969289725499878566253048867033095150518452126944989251596392079421452606508516052325614861938282489838000815085351564642761700832096483117944401971780149213345335903336672376719229722069970766055482452247416927774637522135201716231722137632445699154022395494158227418930589911746931773776518735850032318014432883916374243795854695691221774098948611515564046609565094538115520921863711518684562543275047870530006998423140180169421109105925493596116719457630962328831271268328501760321771680400249657674186927113215573270049935709942324416387089242427584407651215572676037924765341808984312676941110313165951429479377670698881249643421933287404390485538222160837088907598277390184204138197811025854537088586701450623578513960109987476052535450100439353062072439709976445146790993381448994644609780957731953604938734950026860564555693224229691815630293922487606470873431166384205442489628760213650246991893040112513103835085621908060270866604873585849001704200923929789193938125116798421788115209259130435572321635660895603514383883939018953166274355609970015699780289236362349895374653428746875

Bây giờ một cách tiếp cận khác mà tôi đã áp dụng là thông qua Chia và Kết hợp thông qua đệ quy

tức là Fib (n) = fib (n-1) + Fib (n-2) và sau đó đệ quy thêm cho n-1 & n-2 ..... cho đến 2 & 1. được lập trình là -

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;

    }

}

Khi tôi chạy mã cho n = 100.000, kết quả như sau:

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)

Ở trên, bạn có thể thấy StackOverflowError được tạo. Bây giờ lý do cho điều này là quá nhiều đệ quy như -

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

Vì vậy, mỗi mục nhập trong ngăn xếp tạo thêm 2 mục nhập nữa, v.v. ... được biểu thị là -

nhập mô tả hình ảnh ở đây

Cuối cùng, rất nhiều mục sẽ được tạo ra mà hệ thống không thể xử lý trong ngăn xếp và StackOverflowError được ném ra.

Để phòng ngừa: Đối với góc nhìn của ví dụ trên - 1. Tránh sử dụng cách tiếp cận đệ quy hoặc giảm / giới hạn đệ quy bằng một lần chia cấp như nếu n quá lớn thì hãy tách n để hệ thống có thể xử lý trong giới hạn của nó. 2. Sử dụng cách tiếp cận khác, như cách tiếp cận vòng lặp mà tôi đã sử dụng trong mẫu mã đầu tiên. (Tôi hoàn toàn không có ý định làm suy giảm Phân chia & Kết hợp hoặc Đệ quy vì chúng là cách tiếp cận huyền thoại trong nhiều thuật toán nổi tiếng nhất .. ý định của tôi là hạn chế hoặc tránh xa đệ quy nếu tôi nghi ngờ vấn đề tràn ngăn xếp)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.