Oändlig loop
Från Rilpedia
Oändlig loop är inom programmeringen en slags bugg där en loop aldrig avbryts, vilket gör att programmet (eller åtminstone den tråd som kör loopen) slutar svara.
Innehåll |
Förklaring
Antag att vi har en mängd textsträngar som indexeras med heltalen 0, 1, ..., n. För att erhålla strängen med index index
används funktionen GetText
. Det är inte i förhand känt hur många strängar som finns (vi vet ej vad n är), utan funktionen TextExists
används för att avgöra om det finns någon text med indexet index
eller ej. För att skriva ut alla textsträngar används följande kod:
index := 0; while TextExists(index) do begin writeln(GetText(index)); index := index + 1; end;
Första raden sätter index
till noll. Sedan skrivs texten GetText(index)
ut, index
ökas med ett, texten GetText(index)
skrivs ut igen med detta nya värde på index
och så vidare ända tills TextExists(index)
ger värdet "falskt", och loopen avbryts. En tankspridd programmerare kan lätt glömma raden index := index + 1
:
index := 0; while TextExists(index) do begin writeln(GetText(index)); end;
Det som då händer är att index
aldrig ökas från noll till ett, och att påståendet TextExists(index)
då aldrig blir falskt. Resultatet blir att kommandot writeln(GetText(0))
utförs om och om i all oändlighet. Vi har fått en oändlig loop, där programmet skriver ut texten GetText(0)
om och om igen, utan att svara på några andra kommandon, tills någon dödar processen manuellt (t.ex. genom Aktivitetshanteraren i Windows). Osparade data i programmet går då förlorade.
Tolkning av begreppet "oändlig"
Koden nedan ser ut som ett typexempel på en oändlig loop:
i := 0; while 1+1=2 do begin i := i + 1; end;
Eftersom påståendet 1+1=2
alltid är sant, kommer loopen aldrig att avbrytas på normalt sett. Men varje gång loopen körs ökar värdet på heltalsvariabeln i
, och till slut kommer värdet att nå det högsta möjliga tal som datorn kan lagra i variabeln. Vanligtvis kommer då loopen att avbrytas på grund av detta fel (engelska: integer overflow).
Andra typer av oändliga loopar
Den typ av oändlig loop som beskrevs ovan handlar om en egentlig loop som aldrig avbryts. En liknande typ av bugg, som också kan kallas oändlig "loop", inträffar då en serie av rekursiva funktionsanrop aldrig avslutas. Namnet "oändlig loop" motiveras av att effekten av buggen liknar den som erhålles vid en egentlig oändlig loop. Betrakta exemplet nedan.
function DoSomething(x: integer); begin result := DoSomething(x); end;
När funktionen DoSomething
anropas kommer samma funktion DoSomething
att anropas på nytt i all "oändlighet". Citationstecknen kommer av att felet stack overflow så småningom inträffar och bör avbryta rekursionen.
Notera emellertid att rekursiva funktionsanrop inte måste ge upphov till oändliga loopar, utan detta sker endast om rekursionen aldrig avbryts. Koden nedan visar hur en rekursiv metod kan användas för att beräkna fakultet:
function Fact(n: integer); begin if n = 0 then result := 1 else result := n*Fact(n-1); end;
Oändliga loopar i gamla operativsystem
I äldre operativsystem, såsom Windows 9x-system, kan en oändlig loop i ett program få hela systemet (datorn) att sluta svara.