2016-03-12 19 views
5

Tôi đang cố gắng kiểm tra kích thước của tất cả các biến (loại giá trị) của tôi bằng toán tử sizeof. Tôi trải qua một trong những msdn article nơi nó được viết rằngtoán tử sizeof cung cấp thêm kích thước của cấu trúc trong C#

Đối với các loại khác, kể cả cấu trúc, toán tử sizeof có thể chỉ được sử dụng trong các khối mã không an toàn

và cũng cấu trúc không nên chứa bất kỳ lĩnh vực hoặc tài sản mà nhiều loại tài liệu tham khảo

Đối với điều này, tôi kích hoạt tổng hợp không an toàn về tính chất dự án của tôi và cơ cấu tạo như sau-

struct EmployeeStruct 
{ 
    int empId; 
    long salary;  
} 

và sử dụng nó như sau-

unsafe 
{ 
    size = sizeof(EmployeeStruct); 
} 

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

Ở đây tôi nhận được đầu ra như Kích thước của loại theo byte là: 16 Tuy nhiên bằng cách nhìn vào cấu trúc nó nên là 12 (4 cho int và 8 trong thời gian dài). Ai đó có thể giúp tôi hiểu ở đây rằng tại sao tôi nhận được thêm 4 byte không?

+0

Liên kết bạn đã cung cấp cho bạn: "trong khi sizeof trả về kích thước vì nó đã được phân bổ theo thời gian chạy ngôn ngữ chung **, bao gồm mọi phần đệm **" – DavidG

+0

@EugenePodskal Nó thay đổi rất nhiều - những người đang tìm kiếm câu trả lời một vấn đề trên C# sẽ không xem xét các câu hỏi về C, chúng là các ngôn ngữ rất khác nhau, ngay cả khi câu trả lời là như nhau. –

+0

@GediminasMasaitis Sau đó, họ sẽ tìm thấy câu hỏi này và đọc các bản sao (tốt, ít nhất là họ nên). Nhưng nếu bạn nghĩ rằng nó là giá trị nỗ lực, sau đó bạn có thể viết một câu trả lời C# -specific chính xác thích hợp. Trong trường hợp đó, tôi cũng khuyên bạn nên đổi tên câu hỏi thành giá trị "sizeof trả về giá trị lớn hơn" và có thể tìm kiếm dễ dàng hơn ". –

Trả lời

1

Bạn không cần sử dụng mã không an toàn. Được khuyến nghị sử dụng System.Runtime.InteropServices.Marshal.SizeOf()

ví dụ: Marshal.SizeOf (new EmployeeStruct());

Đó trở lại 16 thay vì 12, vì kích thước gói mặc định trong bộ nhớ là 8.

Vì vậy, đối với:

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

// trở lại 16 thay vì 12 (vì đơn vị phút de 8)

cho:

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

// trở lại 16 quá

và cho

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

trở lại 24 thay vì 20 (vì đơn vị de min là 8)

Tôi không biết những gì bạn muốn, nhưng nếu bạn cần tổng của mỗi kích thước lĩnh vực, bạn có thể thử với chức năng này:

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

nó trả 12 thay vì 16, đối với trường hợp của bạn, và bạn có thể sử dụng nó cho các cấu trúc phức tạp, ví dụ:

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) sẽ trả về 24 thay vì 32, nhưng hãy nhớ, kích thước thực trên bộ nhớ là 32, trình biên dịch sử dụng 32 byte để gán bộ nhớ.

Trân trọng.

+0

Nhưng sau đó tại sao một cấu trúc với ba 'int' có kích thước 12 và không 16? –

+0

Thnx Gonzalo. Nhưng đó không phải là sự thật rằng System.Runtime.InteropServices.Marshal.SizeOf trả về kích thước được quản lý không được quản lý sau khi marshelling? Chúng ta không có cách nào để có được kích thước được quản lý hoặc CLR đúng không? –

+0

Tôi đã chỉnh sửa câu trả lời của mình, có thể tôi có thể giúp bạn. Trân trọng. – Gonzalo

Các vấn đề liên quan