Bláznivé chování statické proměnné – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Bláznivé chování statické proměnné – C / C++ – Fórum – Programujte.comBláznivé chování statické proměnné – C / C++ – Fórum – Programujte.com

 

Štěpán
~ Anonymní uživatel
126 příspěvků
12. 9. 2011   #1
-
0
-

Ahoj, myslel jsem, že v C(++) už mě nic nepřekvapí, prošel jsem vším od složitých výpočetních algoritmů až po DirectD3.

Už přes půl roku programuji ve vývojovém prostředí Pelles C aplikaci pro Windows Mobile.

Programuji v ryzím C, nikoli v C++.

Má asi 10 000 řádků. Vše mám jednom souboru main.c

A teď to příjde:

1. problém nastal už dávno při volání rekurzivní funkce. Faktoriál rekurzí mi šel, jiný výpočet rekurzí ale z mně neznámého důvodu padal. Tehdy jsem to neřešil a napsal jsem to iterací...

2. Včera mi ale program totálně zešílel. Půl roku plně funkční aplikace přestala od základu fungovat. Dlouho jsem to ladil (bez debugeru), výsledek mě šokoval o to víc. Když jsem definoval (úplně zbytečnou, nepoužívanou) proměnnou

uvnitř jedné z funkcí double dbl[10]; bylo vše v pořádku.

když jsem definoval

double dbl[100];

program se najednou sesypal.

3. Toto jsem "vyřešil" tak, že jsem obrovské bloky zdrojáku dal z jedné velké do více menších funkcí a zas to fungovalo...

4. Dnes ale nastal error ještě větší, když mi neznámo kde program začal mazat obsah jedné proměnné (definované pro celý soubor main.c "static int g_iTestLevel;".

Po pěti hodinách jsem přišel na to, že když ji definuji jako static (takto mám všechny proměnné) program mi ji někde vynuluje. Když klíčové slovo static vynechám, program funguje jako švýcarské hodinky.

Co se to s tou aplikací proboha děje? Mám mobil s cca 256 MB RAM, ta aplikace žere maximálně 5MB (spíše 2MB), systém má volných cca 150MB. Tak s pamětí v mobilu by problém být neměl.

Máte někdo zkušenosti s podobným nesmyslným chováním aplikace na Windows Mobile?

-//- s podobnými nesmysly ve vývojovým prostředím Pelles C? Ono někdy se chová fakt zvláštně...

Je problém, že mám vše v jednom (a pěkně nepřehledném:D) souboru main.c?

Je nějaký důvod (z pohledu funkčnosti, ne přehlednosti) psát více krátkých funkcí, mít více malých xxx.c souborů než jeden velký main.c? Já už opravdu nevím, obávám se, že jednou tu aplikaci už přestanu zvládat.

Děkuji za nápady.

Nahlásit jako SPAM
IP: 88.100.48.–
KIIV
~ Moderátor
+43
God of flame
12. 9. 2011   #2
-
0
-

urcite si ses vedom toho, ze static => pro vsechny volani stejne funkce jsou tam stejna data

dal co popisujes, tak budes mit problemy spis s prepisovanim pameti, co ti nepatri a tak podobne

staticke promenne (ale ne s klicovym slovem static!) maji jen omezenou velikost (na normalnim pocitaci suma = cca 2MB - kdyz pujdes na vic tak uz se nezkompiluje)

byt tebou proste zatracene dobre projdu co program dela, proc vubec nekde pouzivas klicove slovo static a tak podobne

Edit: jo a jeste - nemuze se stat, ze pri rekurzich dojde k preteceni haldy/zasobniku a prepisovani dat navzajem? u jednocipu to hrozi, nevim jak na mobilech

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Štěpán
~ Anonymní uživatel
126 příspěvků
12. 9. 2011   #3
-
0
-

#2 KIIV
Ano, vstupní data jsou totožná. Program nefunguje, smažu slovo static a program funguje... Nechápu to.

Ale k tomu, co píšeš...

Slovo static mám u všech g_ proměnných, tedy u těch pro celý soubor main.c.

Nevím ani proč, mám to smazat?  

Jinak tyto proměnné mohou zabírat docela dost místa,

mám tu i takové jako double[13][13][13][13], long[13][13][13][13], 12ti bajtová struktura[13][13][101]...

Je to lepší alokovat pomocí HeapAlloc nebo malloc? Také mám funkce o 2000 řádcích, nevadí to? Díky za radu!

PS: Ta rekurze pro mě tedy momentálně není na pořadu dne, spíše jsem ji uvedl, že mě to C někdy pěkně vykolejí... Také jsem v některých případech neuspěl s vytvořením funkce se 4 parametry... Dokud to šlo, tak jsem se takovým problémům vyhýbal, ale teď už to zašlo daleko...

Nahlásit jako SPAM
IP: 88.100.48.–
KIIV
~ Moderátor
+43
God of flame
12. 9. 2011   #4
-
0
-

no globalni promenne jsou tak jak tak videt vsude v ramci jednoho souboru - urcite je nemusis mit "static" - se spis hodi uvnitr nejaky funkce - jako treba pocitadlo volani nebo cokoliv co si potrebuje pamatovat predchozi stavy

urcite si over, kolik mas k dispozici mista.. tydle pole muzou byt pomerne velky - na to uz byva fakt lepsi pouzit malloc (a nemusis mit ani 4rozmerny... staci kdyz si dokazes vypocitat z tech 4rozmeru spravny offset v ramci jednorozmerneho pole, ktere ma stejny pocet polozek jako to 4rozmerne)

jen to cos zminil muze mit cca pres 0,5MB a tezko rict, kolik mas mista + pokud program pouziva vlakna tak ma jeste mnohem mensi misto nez obycejny program!

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Štěpán
~ Anonymní uživatel
126 příspěvků
12. 9. 2011   #5
-
0
-

#4 KIIV
No já to tedy předělám na malloc, přišlo mi to takové komfortní psát přímo 4 indexy do závorek, ale ta cena za to je příliš vysoká, když kvůli tomu padá aplikace... Tak já vezmu papír, tužku, vypočítám správný offset v jednorozměrném poli, vytvořím ho mallocem / HeapAllocem, přepíšu to a pak dám vědět jestli to pomohlo...

Nahlásit jako SPAM
IP: 88.100.48.–
voty+1
Návštěvník
13. 9. 2011   #6
-
0
-

Mno, dle popisu mi to stejně připadá jako (nechtěné) přepisování si paměti, takže přepis na malloc tento problém může buďto skrýt, nebo naopak to může spadnout mnohem dříve. Jediný rozdíl (z pohledu běhu programu) je ten, že globální proměnné jsou umístěny jinde než ty "vytvořené" pomocí malloc.

Samozřejmě neznám paměťový model, který se používá u této aplikace. Bez toho těžko soudit, zda tam může být i jiný zádrhel, ale jsem si téměř jist, že by neměl. Téměř :)

Nahlásit jako SPAM
IP: 85.161.235.–
Jednu rozbil a tu druhou ztratil.
Štěpán
~ Anonymní uživatel
126 příspěvků
13. 9. 2011   #7
-
0
-

Tak ty největší monstra jsem přestěhoval do mallocu, bylo toho skoro 1MB. statiky jsem všude smazal a běží to. Teď je jen otázka, jak říká voty, jestli to problém vyřešilo, nebo jen skrylo. Ale vzhledem ke struktuře programu těžko věřím, že bych ji mohl mazat přímo od sebe, půl roku to fungovalo dobře a ty poslední řádky kódu, které jsem přidával včera a předevčírem, se zkrátka spouští až někde hluboko v programu, nikoli hned při spuštění. Ale každý chybujeme, nemožné to není. V každém případě teď program běží zdá se na 100%.

Díky za pomoc.

Nahlásit jako SPAM
IP: 88.100.48.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 25 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý