2016-03-12 15 views
5

Próbuję sprawdzić rozmiar wszystkich moich zmiennych (typów wartości) za pomocą operatora sizeof. I przeszedł jeden z msdn article gdzie jest napisane, żeoperator sizeof daje dodatkowy rozmiar struktury w C#

Dla wszystkich innych typów, w tym elemencie, operator sizeof mogą być wykorzystane tylko w niebezpiecznych bloków kodu

a także kodowanym nie powinny zawierać pola lub właściwości, które są typy referencyjne

Do tego mam włączony niebezpieczny kompilację w moich właściwości projektu i stworzył strukturę następujące znaczenie:

struct EmployeeStruct 
{ 
    int empId; 
    long salary;  
} 

i wykorzystał je następujące znaczenie:

unsafe 
{ 
    size = sizeof(EmployeeStruct); 
} 

Console.WriteLine("Size of type in bytes is: {0}", size); 

Tutaj jestem coraz wyjścia jak rozmiar w bajtach typu jest: 16 jednak patrząc na strukturę powinno być 12 (4 i 8 do int na długo). Czy ktoś może mi pomóc zrozumieć, dlaczego otrzymuję 4-bajtowy dodatkowy rozmiar?

+0

Podany link mówi: "while sizeof zwraca rozmiar, ponieważ został przydzielony przez wspólne środowisko uruchomieniowe języka, ** w tym wszelkie dopełnienie **" – DavidG

+0

@EugenePodskal To dużo zmienia - ludzie, którzy szukają odpowiedzi problem na C# nie będzie wyglądać na pytania o C, są bardzo różne języki, nawet jeśli odpowiedź jest taka sama. –

+0

@GediminasMasaitis Następnie znajdą to pytanie i przeczytają duplikat (cóż, przynajmniej powinni). Ale jeśli uważasz, że to jest warte wysiłku, możesz napisać właściwą kanoniczną odpowiedź C#. W takim przypadku zaleciłbym również zmianę nazwy pytania na łatwiejszy do wyszukania i do punktu "sizeof zwraca wartość większą niż oczekiwana" lub coś podobnego do tej linii. –

Odpowiedz

1

Nie musisz używać niebezpiecznego kodu. Zaleca się używanie System.Runtime.InteropServices.Marshal.SizeOf()

np .: Marshal.SizeOf (new EmployeeStruct());

że powrót 16 zamiast 12, ponieważ rozmiar pakietu domyślnego jest pamięć 8.

Tak więc, dla:

struct EmployeeStruct 
{ 
    int empId; // 4 bytes 
    long salary; 8 bytes 
} 

// powrotu 16 zamiast 12 (ponieważ de urządzenie MIN 8)

dla:

struct EmployeeStruct 
{ 
    int empId; // 4 bytes 
    int empAge; // 4 bytes 
    long salary; 8 bytes 
    } 

// zwraca 16 zbyt

i

struct EmployeeStruct 
    { 
     int empId; // 4 bytes 
     int empAge; // 4 bytes 
     int IdCompany; // 4 bytes 
     long salary; 8 bytes 
    } 

zamian 24 zamiast 20 min (bo de urządzenie jest 8)

nie wiem, co chcesz, ale jeśli trzeba sumę każdego rozmiaru pola, można spróbuj z tej funkcji:

public int SizeOf(Type t) 
    { 
     int s = 0; 
     var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); 
     foreach (var f in fields) 
     { 
      var x = f.FieldType; 
      s += x.IsPrimitive ? Marshal.SizeOf(x) : SizeOf(x); 
     } 

     return s; 
    } 

zwraca ona 12 zamiast 16, w Twoim przypadku, i można go używać dla złożonych struktur, np:

struct EmployeeStruct 
    { 
     int field1; // 4 bytes 
     long field2; // 8 bytes 
     Person p; // 12 bytes 
    } 

    struct Person 
    { 
     int field1; // 4 bytes 
     long field2; // 8 bytes 
    } 

SizeOf (typeof (EmployeeStruct) zwróci 24 zamiast 32, ale pamiętaj, że REAL SIZE ON MEMORY ma 32, kompilator używa 32 bajtów do przypisania pamięci.

Pozdrawiam.

+0

Ale dlaczego struktura z trzema 'int' ma rozmiar 12, a nie 16? –

+0

Thnx Gonzalo. Ale czy to nie prawda, że ​​System.Runtime.InteropServices.Marshal.SizeOf zwraca niezarządzany przydzielony rozmiar po marshalling? Czy nie mamy żadnego sposobu na uzyskanie prawidłowego rozmiaru przydzielonego lub przypisanego CLR? –

+0

Edytowałem swoją odpowiedź, może pomogę ci. Pozdrowienia. – Gonzalo