Miért nem működik az alábbi kódrészlet úgy, ahogy kellene?
Van egy egyszerű kis program, ami nálam, Linux-on - de másoknál Windows-on is - működik, de egyik ismerősömnél nem (Windows 10-et használ). Nekem online mutatta meg a problémát és nincs Windows a gépemen, hogy azon tudjam csekkolni a dolgot (meg, mint írtam, nálam csont nélkül működik). Nem tudtam rá mit mondani, de azért érdekelne, hogy ki mit szól itt rá.
Egy C nyelven írt faék egyszerűségű (épp ezért is zavar, hogy nem tudom, mi a gond vele) függvényről van szó, ami annyit tesz, hogy egy struktúratömb tartalmát kiírja egy szöveges állományba:
void fajlbaIr(lakos *lakosok, int hossz)
{
int i;
FILE *fm = fopen("lakosLista.txt", "w");
for(i = 0; i < hossz; i++){
fprintf(fm, "%s\t%s\n", lakosok[i].nev, lakosok[i].cim);
}
fflush(fm); fclose(fm);
}
A lakosLista.txt állomány létrejön, de üres marad. Amikor megkértem, hogy valamit tegyen bele még a ciklusmagba, annyi derült ki, a vezérlés bejutott a magba, de az fprintf() függvényen nem jutott túl, majd a program futása leállt.
Esetleg a fájlpointert is NULL-ról indíthatta volna és arra is rátesztelhetett volna, de ez akkor nem jutott eszembe, mert magam is épp nyakig voltam mindennel, csak most, hogy "üresjáratban" vagyok kezdett el megint érdekelni a dolog.
(Azt most hagyjuk, hogy az ismerősömet érdekli-e még... engem igen. :) )
Se hibaüzenet se semmi?
Első körben fprintf helyett simán printf stdout-ra, aztán ha nincs meg a hiba, akkor fordítsd le -g -vel és menj végig rajta gdb-vel.
Az ismerős gépén nem volt sem error, sem warning a fordításkor. Futtatáskor volt csak probléma.
A "gond" az, hogy nálam minden flottúl megy, egy másik függvény - printf -et használva - kilistázza a tömböt és a fenti függvény is kiírja fprintf -fel a tartalmát a szöveges állományba.
Sajnos nem vagyok ott, ahol a gond van, így nem tudom az ő rendszerén tesztelni a dolgot. (Csak l'art pour l'art érdekel.) Mindenesetre köszi, ha hazaértem este, megnézem majd a -g opcióval is. Bár nálam nem valószínű, hogy hiba lesz.
Na, közben megint akadt egy kis időm, így belenéztem a kódba, s meglett a bibi.
A lényeg az, hogy amikor első körben, gyorsan átnéztük, csak az error -okat és a warning -okat ráztam gatyába tűzoltás gyanánt, utána pedig kizárólag a kérdéses - fentebb idézett - rövidke részt vizsgáltam, ahol ugye nem találtam hibát.
Most átpörgettem az egész programmind az 500 sorát, s rájöttem, mi az, ami a tapasztaltakká eszkalálódik. Nyilván nem szintaktikai hiba volt, ez eddig is világos volt.
Az illető, amikor bővíteni akarta a struktúratömböt, csak az elemek számát tároló változót inkrementálta, viszont realloc() függvényt nem használt.
De még, ha használt is volna, akkor sem működött volna nála a dolog, mert ugye a main -ben volt egy "lakos *lakosok" pointer, ami még a malloc() által rá lett fordítva a lefoglalt blokkra, azonban....
.... az a függvény, aminek a feladata a tömb bővítése is volt (ahol a realloc() -ot is kellett volna használnia) a híváskor nem a "&lakosok" -at kapta meg paraméterül, hanem csak a "lakosok"-at.
Azaz, még, ha használta volna is a realloc() -ot az nem a main lokális "lakosok" nevű pointerét forgatta volna rá a realloc() által visszaadott címre, hanem a hívott függvény saját pointerét (ami a híváskor ugye megkapta a main-beli "lakosok" nevű pointer által tárolt címet).
Összegezve:
- egyfelől, csak az elemek számát növelte, de a foglalt blokk méretét nem, mert
- nem használt realloc() -ot
- másfelől pedig, még, ha használt is volna realloc() -ot, akkor is
gond lett volna, mert csak "sima" pointert használt ott, ahol mutatót jelölő mutatóval kellett volna dolgozni és ugye annál alkalmazni a pointer dereference műveletet valahogy így:
*l = (lakos *)realloc(*l, ++(*h) * sizeof(lakos));
, ahol "l" a "lakosok" pointerre mutató pointer, "h" pedig a "hossz" változót jelölő mutató.
Volt még más gebasz is, de ezek voltak a lényegi hibák, s ezek összessége vezetett el végül ahhoz, amit leírtam a kérdésben. Mindenesetre, gatyába ráztam a programját, elküldtem neki, s most nála is csont nélkül működik.
Most már csak az a rejtély, hogy az eredeti nálam miért működött... :)
Erre csak tippelni tudok. Esetleg más a "dialektus", az én fordítóm talán többbővítménnyel üzemel, kvázi "engedékenyebb". Ő ugye egy Win10-es rendszeren írt, codeblocks -ban (gondolom mingw -t használva), én meg egy LMDE4 -es Linuxon a telepítéssel érkezett gcc -vel fordítottam a forrást. Vagy ki tudja...
Mindenesetre, köszönöm a segítségeket és "Bala'zs" felajánlását is!
De inkább kivártam, míg megint lesz egy kis szünetem, s nekiálltam magam. Mégiscsak piszkálta az önértékelésemet, hogy oldjam már meg saját magam a gondot (még, ha nem is az én problémám volt) :)
Hát igen, a C szépségei :D
Ha nem lennének a nyelvben pointerek, kb. hótunalmas gyerekjáték lenne az egész. Így legalább vannak benne kihívások :D
További kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!