Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Chyba v Delphi?

[img]chyba7vc.png[/img]
Chcem sa spytat kedy vznikne takato chyba v Delphi? U mna sa to stalo ked som do premennej typu record pridal dalsie dve premenne rovnakeho typu (tie dve pridane su rovnakeho typu a to array[1..(X*X)-X]of Byte). Pokial som pridal iba jednu tak sa nic nestalo ale po pridani druhej sa objavila tato chyba. Stalo sa to na zaciatku podprogramu pri jeho Begin. Do premennych sa nic nevkladalo ani sa s nimi nijako nepracovalo. Nakoniec som to vyriesil zmenou tych premennych za array[1..X-1]of Byte. Z mojho laickeho pohladu to vyzera ako keby tie dve predchadzajuce struktury boli na Delphi moc velke. Aky je vas nazor?

Předmět Autor Datum
Ano, dynamicke premenne (v procedurach apod.) sa ukladaju do zasobnika, a ten nie je nekonecny (je p…
MM.. 15.05.2006 02:03
MM..
V mojom pripade X=28. Este by som chcel vediet co sa mysli "dynamicke premenne". Ja si pod tym preds…
Andrej 15.05.2006 02:18
Andrej
Bol by som vdacni keby ste uviedly cast kodu ako by to vizeralo s "(z heap), prip. cez new objekt".…
Andrej 15.05.2006 02:38
Andrej
Uff sorry ale ty nemas k tomu delphi ziaden manual? RTL.asp Ale radsej to asi rob ako objekt, Delphi…
MM.. 15.05.2006 02:58
MM..
Ja uz som sa tu v jednom prispevku pytal ake su limity Delphi pri praci s RAM a o ziadnom zasobniku…
Andrej 15.05.2006 03:20
Andrej
Si mal spomenut ze sa pytas o obmedzeniach zasobnika, nie pamate ;-) Treba na to davat pozor, dilema…
MM.. 15.05.2006 03:25
MM..
"Si mal spomenut ze sa pytas o obmedzeniach zasobnika, nie pamate" to som spomenut nemohol pretoze s…
Andrej 15.05.2006 03:40
Andrej
:-) Tak neviem ako si takymi polom zaplnil 1MB stack. Pouzi dynamicke pole. A pri predavani do proce…
MM.. 15.05.2006 03:48
MM..
Tych poli je tam niekolko ci uz [1..X] alebo [1..X,1..X] a tie sa niektore skladaju este z recordov…
Andrej 15.05.2006 04:03
Andrej
Zasobnik je uz rezervovany, proste existuje :-) Pri vstupe do procedury sa rezervuje miesto zo zasob…
MM.. 15.05.2006 04:21
MM..
Akože nikto? A čítal si čo som písal ja? Presne to isté čo teraz ty som urobil v Turbo Pascale. A od…
msx. 15.05.2006 12:57
msx.
Ty si tam pisal o Turbo Pascale a Dose a kedze ja som sa pytal na Delphi a Windows tak som dospel k…
Andrej 15.05.2006 16:49
Andrej
Do definicii delphi premennych az tak nevidim, robim v C++, vseobecne premenna moze byt naalokovana…
MM.. 15.05.2006 02:46
MM..
Vdaka za odpoved. Este ma predsa len zaujima ak by cela ta struktura bola v hlavnom programe a nie v…
Andrej 15.05.2006 03:06
Andrej
Kukni linky co som dal vyssie. Volaju to tam global/local premenne, nie "staticka" ako v C (co je vy…
MM.. 15.05.2006 03:15
MM..
Pozrel som sa do Project Options karta Linker a tam je Memory Sizes ako Min Stack Size $00004000 B a…
Andrej 15.05.2006 19:08
Andrej
IMHO to nie je 100000B ale hexadecimalne 100000, co je 1MB. Ano mozes si to zvysit (pisal som ti to…
MM.. 15.05.2006 20:06
MM..
Vdaka ja si tie odkazy precitam a pozrem sa ako je to tam riesene. Zatial mi staci moznost zvacsit s…
Andrej 15.05.2006 20:22
Andrej
Ja ešte doplním, že ak je program napísaný tak, že nekontroluje pretečenie zásobníka (čiže by ti nev…
msx. 15.05.2006 22:47
msx.
To mas pravdu, bohuzel je to tak, mne zase vic stve ze nove delphi maj udelanou tak blbe napovedu (p…
virus 16.05.2006 04:03
virus
Nemas pravdu. To co popisujes nie je problem nedostatku zasobnika, to co popisujes je zneuzitie chyb…
MM.. 16.05.2006 11:57
MM..
vďaka tejto chybe Mal som na mysli chybu programátora, vďaka ktorej vypíše Delphi chybu, ktorú sem…
msx. 16.05.2006 13:36
msx.
To spolu nesuvisi! :-) Pri chybe o ktorej pises sa nevypise chybove hlasenie "stack overflow". Prost… poslední
MM.. 16.05.2006 13:41
MM..

Ano, dynamicke premenne (v procedurach apod.) sa ukladaju do zasobnika, a ten nie je nekonecny (je primarne urceny na navratove adresy fcii a predavanie parametrov).
Stack overflow znamena ze zasobnik nestaci.
//Edit: a nie je to "moc velke na Delphi", zasobnik je obmedzeny v kazdom programe, take veci sa proste nerobia.

Chcel si alokovat 2x X na druhu bytov, ak je X dost velke tak to samozrejme moze nastat. Niekde sa da v nastaveniach zvacsit velkost zasobnika, ale nauc sa na taketo veci pouzivat dynamicke pridelovanie pamate (z heap), prip. cez new objekt, apod., v tom pripade mozes alokovat tusim aj celu volnu virtualnu pamat. Pozri si nejaky tutorial o tom.

V mojom pripade X=28. Este by som chcel vediet co sa mysli "dynamicke premenne". Ja si pod tym predstavujem napr. SetLength(var S; NewLength: Integer); ktora nieje znama dopredu ale vytvori sa az pocas (pod)programu. Zmenilo by sa nieco ak by to nebolo v podprograme ale hlavnom programe?

Si mal spomenut ze sa pytas o obmedzeniach zasobnika, nie pamate ;-) Treba na to davat pozor, dilema zasobnik vs. heap je jedna zo zakl. veci ked ide o data.
Inac myslim ze som nasiel dynamicke pole je asi to co potrebujes, vid moj prispevok uplne dole...

P.S. zasobnik je uplne zakladna vec, pouziva ho kazdy program, nesuvisi to ani s Delphi, ani s DOSom. Aj keby si programoval v comkolvek (co vytvara aplikaciu) mal by si rovnaky problem (zasobnik vs. heap).

"Si mal spomenut ze sa pytas o obmedzeniach zasobnika, nie pamate" to som spomenut nemohol pretoze som vtedy este o zasobniku v Delphi nevedel 3-[. V tom mojom programe pracujem s poliami rangeArray : Array[1..X] of rozneCiselneTypy kde X=28; je definovane v sekcii Const v hlavnom programe. Takze pracujem iba so statickymi poliami. Vysledok je ze je to mierne predimenzovane ale pre moje uceli to tak velmi nevadi.
Dakujem za odkazi urcite si to precitam a ked nebudem niecomu rozumiet tak sa tu objavi dalsi moj prispevok na tuto temu :-D

Tych poli je tam niekolko ci uz [1..X] alebo [1..X,1..X] a tie sa niektore skladaju este z recordov ktore obsahuju zase polia [1..X-1] popripade [1..X*X-X]. Takze ako som napisal ono sa to asi nazbiera:-) Ta chyba ako som napisal na zaciatku vznikla pri vstupe do podprogramu kedy sa este nic neurobilo iba sa zrejme zacala rezervovat pamat pre ten zasobnik a kedze su to vsetko staticke polia tak zrejme uz vtedy zistil ze ma malo pamate (pokial to okolo toho zasobnika spravne chapem). Jedina rekurzivne volana procedura je Quicksort(A,B:Byte); takze tym to urcite nebolo.

Zasobnik je uz rezervovany, proste existuje :-) Pri vstupe do procedury sa rezervuje miesto zo zasobnika pre lokalne premenne v procedure. Ak su moc velke tak samozrejme tam vznike problem.

Datove struktury si treba poriadne premysliet este predtym nez clovek zacne pisat program, mam pocit ze z toho mas dost gulas poli v poliach (ak som to dobre pochopil [1..X,1..X] recordov [1..X*X] tak v podstate vytvaras pole velkosti az X na stvrtu, co uz urobi aj pol megabyte pri X=28). Skus to dynamicke pole ale hlavne rozmyslaj pri tom ze co je kde v pamati ulozene aby si tam nemal milion poli zbytocnych.

Ty si tam pisal o Turbo Pascale a Dose a kedze ja som sa pytal na Delphi a Windows tak som dospel k mylnemu nazoru ze "zasobnik bolo nieco" iba v Dose s cim sa uz vo Windovse zaoberat nemusim. Vdaka MM.. uz viem ze zasobnikom sa musim zaoberat i vo Windovse.

Do definicii delphi premennych az tak nevidim, robim v C++, vseobecne premenna moze byt naalokovana z memory heap (v C sa to vola "staticke premenne"), konstanty (naozaj nemenne, nie vsetky v sekcii "const" su nutne nemenne) mozu byt v kodovej pamati, a ostatne premenne sa alokuju zo zasobnika pocas behu programu (to som si teraz nazval "dynamicke premenne" aj ked je to dost zavadzajuce), je jedno ci to das do hlavneho programu alebo podprogramu.
Na staticku premennu zabudni ak mas velkost pola zavislu od X.

Ak je X = 28, tak si chcel naalokovat. ca 3kB. Neviem kolko nastavuje Delphi defaultne zasobnik (mohlo by to byt v nastaveniach projektu), je aj mozne ze v tej procedure alebo v hlavnom programe mas uz vela inych premennych alokovanych zo zasobnika ktore zaberaju vela miesta, alebo prenasas do procedury nejake velke pole hodnotou, ale pretecie to az na tychto 3kB.

Mam taky pocit ze objekty delphi sa alokuju z heap nie zo zasobnika, takze ak by to bol objekt malo by to byt OK, ale ako presne to mas urobit ti nepoviem, ty si Delphi programator nie ja :-), ja som ti len chcel napisat: Ano, mas malo zasobnika, urob to tak aby to neslo cez zasobnik.

Ak sa sem kukne Jan Fiala alebo niekto kto robi v Delphi aktivne napise ti k tomu mozno presnejsie.

Vdaka za odpoved. Este ma predsa len zaujima ak by cela ta struktura bola v hlavnom programe a nie v podprograme i tam by bol problem so zasobnikom (pokial som to spravne pochopil tak zasobnik umoznuje prenos udajov medzi podprogramami a hlavnym programom)? Je pravda ze v tom mojom programe pracujem s niekolkymi typmi zaznamov ktore su potom umiestnene v matici bud [1..X] pripadne [1..X,1..X] takze sa to zrejme nazbiera :-D

Kukni linky co som dal vyssie.
Volaju to tam global/local premenne, nie "staticka" ako v C (co je vystiznejsie ptz. "global"/"local" suvisi s viditelnostou premennej ale to je teraz jedno).
Ak by si to urobil ako globalnu premennu tak by to neslo zo stacku, takze mozes kuknut aj na to
aa060899.htm, sekcia "unit level variables" a "global variables", ale to sa ti asi nepodari, ptz., mas velkost zavislu od momentalneho X.

Tiez davaj pozor co prenasas ako parameter do procedury, ak je tam nejake pole alebo matica tak to prenasaj odkazom nie hodnotou (snad sa to v Delphi da), to je najdolezitejsie.

Ak vytvaras velke matice tak zasadne z heap, nie zo stacku. Co vsetko ide z heap mas v tej linke co som dal vyssie (http://info.borland.com/techpubs/delphi/delphi5/opl g/memory.html), v sekcii "Variables", hlavne vetu
Long strings, wide strings, dynamic arrays, variants, and interfaces are heap-allocated, but their memory is managed automatically.

Takze ak pouzijes jeden z tych objektov (napr. dynamic array prichadza do uvahy) tak to budes mat z heap.
T.j. RTL.asp
Declaring and using dynamic arrays

Pozrel som sa do Project Options karta Linker a tam je Memory Sizes ako Min Stack Size $00004000 B a Max Stack Size $00100000 B. Takze pokial by som sa este stretol s touto chybou tak uz viem kde to mozem zmenit.

Na zaver pokial to dobre chapem tak zasobnik umoznuje prenasanie udajov medzi hlavnym programom a jeho podprogramami (procedurami a funkciami) popripade i proceduri a funkcie mozu mat vlastne proceduri a funkcie. Takze sa toto vsetko deli o zasobnik ktory ma definovanu urcitu velkost (v mojom pripade 100 000 B). Predpokladam ze by to malo fungovat tak ze pokial opustim proceduru alebo funkciu ktora mala lokalne premenne (napr. polia) tak sa zo zasobnika uvolni cast pamati ktoru zaberali?

IMHO to nie je 100000B ale hexadecimalne 100000, co je 1MB.
Ano mozes si to zvysit (pisal som ti to snad hned na zaciatku), ale nie je to rozumne (efektivita, a ak vytvaras data dynamicky tak nevies ci to pri urcitych specialnych vstupoch zas nedrbne kvoli rovnakemu problemu, apod.), pre vacsie mnozstva dat zasadne pouzivat objekty/fcie ktore pracuju s memory heap.

Ano ak opustis podprogram tak sa musi uvolnit zo zasobnika vsetko co sa na zaciatku podprogramu na zasobniku alokovalo, ptz. je nutne aby pri ukoncovani procedury bolo na vrchu zasobnika to, co pri volani procedury - navratova adresa.

Vdaka ja si tie odkazy precitam a pozrem sa ako je to tam riesene. Zatial mi staci moznost zvacsit si to rucne v tom nastaveni. Oznacil by som to za vyriesene. Ak sa stretnem z niecim comu este nebudem rozumiet tak vytvorim nove vlakno s danou temou.

Ja ešte doplním, že ak je program napísaný tak, že nekontroluje pretečenie zásobníka (čiže by ti nevypísalo túto chybu, čo si sem dal), tak to skončí spadnutím programu, pretože sa prepíše návratová adresa podprogramu. V extrémnych prípadoch sa stáva, že vďaka tejto chybe sa hacker nabúra do systému. Píšem síce, že v extrémnych prípadoch, ale tým myslím prítomnosť hackera. Ak prepíše návratovú adresu vhodnou hodnotou (vhodnou preňho), tak sa beh programu síce zrúti, ale riadenie sa korektne odovzdá systému a hacker má voľné pole pôsobnosti. Je to najčastejšia chyba v programoch, ktorá umožňuje nabúrať sytém. Takže veľký pozor na to, hlavne v programoch, ktoré bežia s najvyššími právami. Ak sa nemýlim, dokonca niektoré vírusy takto odpravia do večných lovísť mnohé z antivírov (niekde som to tuším čítal).

Takže ako má Intex vo svojom podpise na živě:;-)

Aj ten najjednoduhší program sa neskôr môže vyvinúť ako veľmi zložitý...

Nemas pravdu. To co popisujes nie je problem nedostatku zasobnika, to co popisujes je zneuzitie chyby programatora ak si nekontroluje velkost vstupu (v pascale by sa to nemalo stavat ptz. pascal interne kontroluje pristupy do pola).
priklad (C/C++):
void SpracujSlovo(char* slovo)
{
char pomocnybuffer[20];
strcpy(pomocnybuffer, slovo); - tu je bezpecnostna diera, hacker ju moze zneuzit ak vie sposobit ze "slovo" bude mat viac ako 20znakov
...
}
Nema to nic spolocne s velkostou zasobnika, ten moze byt aj milion gigabytov stale to bude derave.

Ak by bol maly zasobnik a nekontrolovalo by sa to, tak by si sa dockal pravdepodobne windows hlasky "program proved nelpatnou operaci a bude ukoncen" ptz. by sa prekrocil limit stack segmentu (CPU exception).

To spolu nesuvisi! :-)
Pri chybe o ktorej pises sa nevypise chybove hlasenie "stack overflow". Proste pises o niecom inom. Andrej len pouziva prilis vela velkych lokalnych premennych, to nie je bezpecnostna diera, (neda sa to zneuzit hackerom), je to len problem v tom ze mu nastavena velkost stacku nestaci a program je v tom momente preruseny.

Zpět do poradny Odpovědět na původní otázku Nahoru