2009-07-27 6 views

risposta

3

Sì, la dimensione di una struttura è influenzata dall'architettura. Le strutture C# a 32 bit sono allineate a 4 byte, e in 64 bit sono allineate a 8 byte.

Esempio:

struct Foo 
{ 
    int bar; 
} 

istanze di questa struct occuperanno 4 byte nei processi a 32 bit, e 8 byte nei processi a 64 bit, anche se il "int bar" richiede solo 4 byte su entrambi i processi 32bit e 64bit .

Aggiornamento:

ho fatto alcuni test con questo.Ho scritto questo codice:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication3 
{ 
    struct Bar 
    { 
     int a; 
    } 

    struct Foo 
    { 
     Uri uri; 
     int a; 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Foo[] foo; 
      long fooBefore = System.GC.GetTotalMemory(true); 
      foo = new Foo[10]; 
      long fooAfter = System.GC.GetTotalMemory(true); 

      Bar[] bar; 
      long barBefore = System.GC.GetTotalMemory(true); 
      bar = new Bar[10]; 
      long barAfter = System.GC.GetTotalMemory(true); 

      Foo aFoo = new Foo(); 
      Bar aBar = new Bar(); 

      System.Console.Out.WriteLine(String.Format("[Foo] Size of array of 10: {0}, Marshal size of one: {1}", fooAfter - fooBefore, System.Runtime.InteropServices.Marshal.SizeOf(aFoo))); 
      System.Console.Out.WriteLine(String.Format("[Bar] Size of array of 10: {0}, Marshal size of one: {1}", barAfter - barBefore, System.Runtime.InteropServices.Marshal.SizeOf(aBar))); 
      System.Console.ReadKey(); 
     } 
    } 
} 

Come un processo a 64 bit, ottengo questo output:

[Foo] Size of array of 10: 208, Marshal size of one: 16 
[Bar] Size of array of 10: 88, Marshal size of one: 4 

Come un processo a 32 bit, ottengo questo output:

[Foo] Size of array of 10: 92, Marshal size of one: 8 
[Bar] Size of array of 10: 64, Marshal size of one: 4 

Osservazioni:

  • La semplice struttura, Bar, sembra prendere 4 byte su entrambi i 32 bit e processi a 64 bit
  • L'altra struttura, Foo, sembra prendere 8 byte su 32 bit (4 byte per l'int e 4 byte per il riferimento all'URI), ma 16 byte su 64 bit (4 byte per l'int, 8 byte per il riferimento a Uri, e penso 4 byte per l'allineamento)
+0

JaredPar sembra non essere d'accordo - sai dove si possono ottenere le informazioni? – thecoop

+0

Hmm, forse sono un errore qui. Lo esaminerò un po 'di più. –

+0

Ho aggiornato la risposta con alcuni risultati interessanti. –

6

Non è un valore duro e veloce: è solo una linea guida, una regola empirica. A seconda della situazione esatta, 24 o anche 32 byte potrebbero essere perfettamente giustificabili, ma se la tua struttura diventa così grande dovresti davvero chiedertti se è appropriato come una struttura in primo luogo. Potrebbe essere - nel qual caso prendere il colpo di copiare quei 32 byte ogni volta che si esegue un compito o passare un argomento in un metodo (ecc.) Può essere la cosa giusta da fare; in altri casi dovresti davvero usare una classe.

Per quanto riguarda il modo in cui si determina quanto è grande la propria struttura - di solito è abbastanza ovvio, poiché in genere un tipo di valore contiene solo altri tipi di valore. Se la tua struct contiene riferimenti (o uno IntPtr/UIntPtr), questo è più un problema - ma è piuttosto raro. (Come sottolinea Mehrdad, c'è anche il problema del padding per motivi di allineamento.)

Quindi, ancora una volta, trovo estremamente raro che io voglia scrivere comunque la mia struttura. Qual è la tua situazione?

4

In. Net la maggior parte dei tipi non modifica le dimensioni tra un programma a 32 e 64 bit. Gli unici 2 tipi di valore definiti dal quadro che cambieranno le loro dimensioni basato sulla piattaforma sono

  • IntPtr
  • UIntPtr

A meno che non si dispone di uno di questi, direttamente o indirettamente nella vostra struct, si non dovrebbe cambiare le dimensioni tra le piattaforme.

Come Mehrdad sottolineato, le altre due classi di campi che cambieranno dimensioni basati sulla piattaforma sono

  • puntatori
  • Tipi di riferimento

Tutti questi tipi se cambierà in allo stesso modo. 4 byte su una piattaforma a 32 bit e 8 byte su una piattaforma a 64 bit.