Kezdőoldal » Számítástechnika » Programozás » Elmagyarázná valaki, mi...

Ozmium42 kérdése:

Elmagyarázná valaki, mi történik ebben a kódban egyáltalán? (C)

Figyelt kérdés

Próbálom megérteni, hogyan működnek a C-ben a tömbök, de nem járok sikerrel. Deklarálok egy 10 elemű tömböt, aztán elkezdem feltölteni számokkal. Azt várnám, hogy 9-nél kidobjon egy hibaüzenetet, de ehelyett töltögeti fel tovább, és 2787-nél áll meg.


main()

{

int x[10], y, *p;

for(y=0;1;y++) {x[y]=y+1; printf("%d\n", x[y]);}

}


Nem azt kérem, hogy javítsuk ki a kódot, hanem azt szeretném megérteni, hogy EZ a kód, miért viselkedik úgy, ahogy, miért nem áll meg 10 elemnél, miért különleges a 2787, és mit jelent az, hogy "Szegmentálási hiba (core készült)"


2014. nov. 14. 19:28
1 2
 1/17 A kérdező kommentje:
a *p véletlenül maradt benne
2014. nov. 14. 19:30
 2/17 anonim ***** válasza:

Egyszerű. Az operációs rendszer, amin futtatod, az nem fogja kivédeni a címzésből fakadó hibákat, amíg egy másik program területére nem írsz. Például, ha írsz egy ilyet:


int x[2];

int y;


x[2] = 5;


akkor ez az 5-ös szám az y változódba fog kerülni. Neked azért 2787-nél áll meg, mert a memóriában ott ér véged a te programod, és ott írnál át egy más folyamat memóriaterületére.

2014. nov. 14. 19:37
Hasznos számodra ez a válasz?
 3/17 A kérdező kommentje:

Nálam nem ez történik.


*** stack smashing detected ***: ./World terminated


Az y értéke valamiért 1 lesz. :S

2014. nov. 14. 19:44
 4/17 anonim ***** válasza:

Nem tudom, Windows alatt nekem szépen produkálja az általam leírtakat. Nyilván operációs rendszertől függ ez a dolog.


[link]

2014. nov. 14. 19:48
Hasznos számodra ez a válasz?
 5/17 A kérdező kommentje:
Nekem Ubuntu van. Kicsit a kód is máshogy van megírva. Az utolsó két sort nem ismerem.
2014. nov. 14. 19:51
 6/17 anonim ***** válasza:

Az utolsó két sor egyáltalán nem lényeg. Windows alatt, ha az a system("pause") nem lenne, akkor még azelőtt bezárna a parancssor, mielőtt még látnék valamit. Az a

return EXIT_SUCCESS;

pedig ugyanaz, mintha azt írnád, hogy:

return 0;

Ugye a main függvényben szereplő return a program futási eredményét jelzi, Windows és a legtöbb egyéb rendszerben ez az érték 0, ha a program sikeresen lefutott, és bármi más egész szám, ha nem. De ez a 0 ettől függetlenül még nem garancia, hogy az adott oprendszeren is így lesz. Ellenben az EXIT_SUCCESS minden rendszeren a sikeres kilépést jelenti (EXIT_FAILURE pedig ha sikertelenül ért véget).

2014. nov. 14. 19:57
Hasznos számodra ez a válasz?
 7/17 anonim ***** válasza:

int x[10], y, *p;

for(y=0;1;y++) {x[y]=y+1; printf("%d\n", x[y]);}


Az x-nek lefoglalsz 10 int-nyi helyet a stacken, majd az elejére állítod a pointert. Emiatt ugye x[0] == *x és x[3] == *(x+3).


A túlindexelést nem ellenőrzi alapból semmi. Ugyanúgy a programod által használt memóriaterületre írkálsz. Viszont az általad használható stack végén az oprendszer pofánvágja a programod, hiszen illegális memóriaterületre írkál.


A következő programot először nézd végig, tippeld meg ír-e ki valamit. (á -> a)

[link]

(Nem saját szerzemény, Coursera Software Security kurzus mintaprogramja. De gyönyörű.)

2014. nov. 14. 23:01
Hasznos számodra ez a válasz?
 8/17 anonim ***** válasza:

Lefoglaltál egy 10 elemű tömböt, majd elkezded kiíratni a tömb elemeit. Az első 10-nél biztos nincs hiba, annyi, hogy memóriaszemetet fogsz kapni, mert nem inicializáltad.


Utána pedig bizonytalan a kód folytatása. Az oprendszer a memóriát felosztja valahogy, van olyan része, amit más program nem írhat, olyan is, amit meg más program nem olvashat, meg olyan is, amit az általad írt program kapja meg veremként + amiket lefoglalsz malloc()-al.

Ha olyan memóriaterületre hivatkozol, amit nem a tiéd (pl x[29]) akkor vagy valami memóraszemetet kapsz vissza vagy pedig hibát. Ez az adott gép adott memóriafelosztásától függ.


A 2787 nem különleges szám, csak a te gépeden éppen a 2787. elemnél léptél ki a stackből, vagy ott talált valami olyan memóriaterületet, ami nem az övé. Az x[n] valójában egy pointer, ami az x[0]-ra mutató pointer + n.


Lényeg: mindig figyelni kell rá, hogy ne hivatkozzunk meg olyan memórarészt, amit nem mi allokáltunk, mert lehet, hogy még Segfault sem lesz, csak memóriaszeméttel dolgozik a program, azt meg nagyon nehéz kijavítani.

2014. nov. 14. 23:06
Hasznos számodra ez a válasz?
 9/17 A kérdező kommentje:

"Lefoglaltál egy 10 elemű tömböt, majd elkezded kiíratni a tömb elemeit. Az első 10-nél biztos nincs hiba, annyi, hogy memóriaszemetet fogsz kapni, mert nem inicializáltad."


Inicializáltam, és 1-től írogatja ki a számokat 2787-ig. Csak azt nem értem, hogy miért megy tovább a 10. elemnél, amikor csak 10 van lefoglalva. Minek foglalom le, ha teljesen figyelmen kívül hagyja, és megy tovább? Ha úgy adok meg tömböt, hogy x[3] = {1, 2, 3}, akkor x[3]=4 értékadásnál már kiírja a hibát. Ha meg úgy, ahogy fentebb, akkor simán tovább folytatja 2787-ig.


Az alloc, malloc dolgokat még ugyanezen program megírása közben szeretném megtanulni, de még addig nem jutottam el.


Wampa: a tippem az lett volna, hogy mivel a func() argumentuma 4-nél hosszabb karakterlánc, ezért hiba lesz, és így is lett.


*** stack smashing detected ***: ./World terminated

Félbeszakítva (core készült)


Ugyanakkor ott van az auth változó, ami 0, és utána nem nyúl hozzá sehol, de mégis if-fel ellenőrzi, tehát úgy vélem, annak az értéknek meg kellett volna változnia, ha ez a példa témába vág, akkor a hosszú string felesleges karaktereinek kellett volna megváltoztatnia az auth változó értékét? Nálam nem ez történt.

2014. nov. 14. 23:50
 10/17 anonim ***** válasza:

"*** stack smashing detected ***: ./World terminated

Félbeszakítva (core készült) "


Ezt mi írja ki??

2014. nov. 15. 03:02
Hasznos számodra ez a válasz?
1 2

Kapcsolódó 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

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!