2016-03-12 50 views
5

Sto provando a controllare la dimensione di tutte le mie variabili (tipi di valore) utilizzando l'operatore sizeof. Ho passato attraverso uno dei msdn article dove è scritto chefornisce una dimensione extra di una struttura in C#

Per tutti gli altri tipi, tra le strutture, l'operatore sizeof può essere utilizzato solo in blocchi di codice non sicuri

e anche le strutture non deve contenere campi o proprietà che sono tipi di riferimento

Per questo, mi hanno permesso di compilazione non sicuro nelle mie proprietà del progetto e la struttura creata i seguenti-

struct EmployeeStruct 
{ 
    int empId; 
    long salary;  
} 

e usavano i seguenti-

unsafe 
{ 
    size = sizeof(EmployeeStruct); 
} 

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

Qui sto ottenendo uscita come formato di tipo in byte è: 16 però, cercando in struttura dovrebbe essere 12 (4 per int e 8 per lungo). Qualcuno può aiutarmi a capire qui perché sto ricevendo una dimensione extra di 4 byte?

+0

Il link che hai indicato ti dice: "mentre sizeof restituisce la dimensione così come è stata allocata dal Common Language Runtime, ** includendo qualsiasi padding **" – DavidG

+0

@EugenePodskal Cambia molto - le persone che cercano risposte a un problema su C# non riguarderà le domande su C, sono lingue molto diverse, anche se la risposta è la stessa. –

+0

@GediminasMasaitis Quindi troveranno questa domanda e leggeranno il duplicato (beh, almeno dovrebbero). Ma se pensi che valga la pena, allora puoi scrivere una risposta specifica canonica specifica per C#. In tal caso, ti consigliamo anche di rinominare la domanda in "dimensione del valore restituito più grande del previsto" più facilmente ricercabile e al punto "lungo la linea. –

risposta

1

Non è necessario utilizzare codice non sicuro. Si consiglia di utilizzare System.Runtime.InteropServices.Marshal.SizeOf()

ad es .: Marshal.SizeOf (new EmployeeStruct());

Tale ritorno 16 invece di 12, perché la dimensione predefinita pacchetto in memoria è 8.

Così, per:

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

// ritorno 16 anziché 12 (perché unità de minimo è 8)

per:

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

// ritorno 16 troppo

0.123.516,41 mila

e per

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

ritorno 24 invece di 20 (a causa de min unità è 8)

non so quello che vuoi, ma se avete bisogno la somma di ogni dimensione del campo, si può provare con questa funzione:

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; 
    } 

esso restituisce 12 anziché 16, per il vostro caso, e lo si può utilizzare per le strutture complesse, ad esempio:

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) restituirà 24 invece 32, ma ricorda che REAL SIZE ON MEMORY è 32, il compilatore usa 32 byte per assegnare memoria.

Saluti.

+0

Ma allora perché una struct con tre 'int' ha una dimensione di 12 e non di 16? –

+0

Thnx Gonzalo. Ma non è vero che System.Runtime.InteropServices.Marshal.SizeOf restituisce le dimensioni allocate non gestite dopo l'espansione? Non abbiamo modo di ottenere la dimensione corretta gestita o CLR allocata? –

+0

Ho modificato la mia risposta, forse posso aiutarti. Saluti. – Gonzalo