C# memóriakezelés hogy is?
Honnan tudom egy változónak mi a memóriacíme?
Ezt hogy tudom beolvasni, ill. módosítani.
Angol nyelvű leírást nyelvtudás hiányában nem sikerült teljesen megérteni. Valaki tud jó könyvet/cikket/videót erről ha esetleg ilyen nincs leírná? 17f
.NET-ben ez nem teljesen így megy, a runtime (illetve garbage collector) bármikor átrakhatja az objektumodat.
De nézz utána a fixed kulcsszónak:
"Honnan tudom egy változónak mi a memóriacíme?"
Ha egy változódnak a memóriabeli címét kell lekérdezned, kénytelen vagy unsafe blokkot használni:
int i = 5;
unsafe {
.. int* i = &i;
}
Vagy ha már a metódusod paraméterei is pointer típusú adatot kérnek be, vagy pointer típusú visszatérési értéke van, az adott metódust unsafe kulcsszóval kell ellátnod:
private static unsafe int* DoSomething(int* A, int* B) {
...
}
Ha a kódod unsafe blokkot vagy metódust tartalmaz, a fordító alapértelmezetten nem fogja lefordítani és hibát fog rá írni - tehát külön be kell állítanod, hogy ezt használni tudd. Ha parancssorból fordítasz, akkor így teheted meg:
csc.exe /unsafe /out:MyAssembly.exe MySource.cs
Visual Studio-ban a Project -> [Projekt neve] Properties -> Build -> Allow unsafe code jelölőnégyzetet kell bepipálnod.
DE! Ez nagyon jó okkal van ilyen bonyolultan megoldva, mert nagyon-nagyon ritka esetekben van ilyenre szükséged. Alapesetben a .NET futtatókörnyezet nyilvántartja neked a változóidat és az általad létrehozott objektumaidat, így azokat a szemétgyűjtögető (garbage collector) fel tudja szabadítani, ha nincs rá hivatkozás. Pointerek esetében erre nem képes, tehát innentől teljesen a te kezedben múlik, hogy az általad lefoglalt memóriaterületeket felszabadítsd. Éppen ezért nagyon veszélyes tud lenni, mert elég egy kis figyelmetlenség és rögtön kész a memóriaszivárgás (memory leak - ha nem szabadítasz fel valamit, amire már nincs szükséged).
Általában unsafe kódra akkor szokott szükség lenni, ha natív kódot kell meghívnod, amit mondjuk C-ben vagy C++-ban írtak meg és nem tudod a .NET-es típusokat marshaling-gal egyeztetni a natív típusokkal.
Minden más eset megoldható pointerek nélkül is, amire be lettek vezetve a ref és az out kulcsszavak is - ha például két változó értékeinek felcserélésére akarsz egy metódust:
public void Swap(ref int A, ref int B) {
.. int Temp = A;
.. A = B;
.. B = Temp;
}
int First = 5;
int Second = 6;
Swap(ref First, ref Second);
Ha pedig egy metódusod két eredményt is vissza akar adni:
public void SumAndSub(int A, int B, out Sum, out Sub) {
.. Sum = A+B;
.. Sub = A-B;
}
int Sum, Sub;
SumAndSub(5, 6, out Sum, out Sub);
"egy változónak mi a memóriacíme"
#7-es válaszoló jól írja, de tegyük hozzá, hogy ez a virtuális memóriában lévő címet jelenti, nem a fizikai címet. Nem igazán világos, hogy neked melyik kell, valószínűleg a virtuális, az viszont processzenként egyedi, tehát minden processz úgy látja a saját címtartományát, mintha csak ő használná azt, és ez van leképezve több lépésben (sw és hw) fizikai címekké. Nem véletlen, hogy a CE is kernel modult használ ehhez.
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, 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!