2009-09-08 63 views
5

Tôi đang đấu tranh để hiểu khái niệm này: Tôi có một định nghĩa kích thước cố định:Mảng bên trong cấu trúc trong C

(từ http://msdn.microsoft.com/pt-br/library/aa931918.aspx)

typedef struct _FlashRegion { 
    REGION_TYPE regionType; 
    DWORD dwStartPhysBlock; 
    DWORD dwNumPhysBlocks; 
    DWORD dwNumLogicalBlocks; 
    DWORD dwSectorsPerBlock; 
    DWORD dwBytesPerBlock; 
    DWORD dwCompactBlocks; 
} FlashRegion, *PFlashRegion; 

FlashRegion struct này, được sử dụng trong này struct khác: (từ: http://msdn.microsoft.com/pt-br/library/aa932688.aspx)

typedef struct _FlashInfoEx { 
    DWORD cbSize; 
    FLASH_TYPEflashType; 
    DWORD dwNumBlocks; 
    WORD dwDataBytesPerSector; 
    DWORD dwNumRegions; 
    FlashRegion region[1]; 
} FlashInfoEx, *PFlashInfoEx; 

vấn đề là, tôi có thể có một số biến của FlashRegions bên trong một FlashInfoEx. Chức năng rằng Tôi đang gỡ lỗi không một nơi nào đó trong các mã:

memcpy (pFlashInfoEx->region, g_pStorageDesc->pRegionTable, 
     g_pStorageDesc->dwNumRegions * sizeof(FlashRegion)); 

đó có nghĩa là nó sao chép một số lượng khu vực để pFlashInfoEx (mà tôi vượt qua trong các cuộc gọi của hàm);

Vì vậy, mã sẽ ghi đè bộ nhớ nếu dwNumRegions lớn hơn một. Nếu đó là trường hợp, tôi có nên tạo một FlashRegion [FIXED_SIZE] trong mã của tôi và bằng cách nào đó đặt/ghi đè trong vùng FlashInfoEx-> không? Làm thế nào để làm điều đó?

Cảm ơn, Marcelo

Trả lời

6

Khái niệm này là trong khi FlashRegion trông giống như một cấu trúc kích thước cố định, nó thực sự là động cỡ. Phép thuật được thực hiện khi phân bổ cấu trúc - thay vì gọi số (FlashRegion*)malloc(sizeof(FlashInfoEx)) hoặc new FlashRegion, bạn gọi một cái gì đó như (FlashRegion*)malloc(sizeof(FlashInfoEx)+sizeof(FlashRegion)*(numRegions-1))

+1

Chà, các bạn nhanh lên đây! Vì vậy, điều đó ngụ ý rằng khu vực phải luôn là thành viên cuối cùng của cấu trúc phải không? Tùy thuộc vào trình biên dịch, đây có phải là một rủi ro không? – Marcelo

+0

Khi xác định cấu trúc để có thể tương tác với bất kỳ API nào bạn cần để có thể xác định bố cục bộ nhớ chính xác của cấu trúc. Tôi nghĩ tiêu chuẩn yêu cầu các thành viên cấu trúc phải được sắp xếp theo thứ tự được chỉ định, nhưng nó không chỉ định căn chỉnh. Trong thực tế tất cả các trình biên dịch cung cấp kiểm soát liên kết là tốt. – Suma

+1

Có, khu vực phải là cuối cùng. Rủi ro? Chỉ trong ý nghĩa rằng C chính nó là nguy hiểm.Đây thực tế là ngôn ngữ được sử dụng như thế nào. Có một lý do mà các ngôn ngữ hiện đại làm cho điều này là không thể, nhưng điều đó không hồi tưởng lại mẫu thiết kế ra khỏi bộ công cụ C89 và C90. – DigitalRoss

2

Đây là một thành ngữ C khá phổ biến cho các cấu trúc có kích thước khác nhau. Để thực hiện công việc này, bạn cần đảm bảo bạn phân bổ đủ bộ nhớ cho kích thước mảng mà bạn muốn, thường là một cái gì đó như

pFlashInfoEx = malloc(offsetof(PFlashInfoEx, region) + g_pStorageDesc->dwNumRegions * sizeof(FlashRegion)); 

tương tác này với việc sử dụng 'mới' trong C++; bạn phải phân bổ bộ nhớ bằng tay:

void *mem = ::operator new(offsetof(PFlashInfoEx, region) + g_pStorageDesc->dwNumRegions * sizeof(FlashRegion)); 
pFlashInfoEx = new(mem) PFlashInfoEx; 
for (int i = 1; i < g_pStorageDesc->dwNumRegions; i++) 
    new (&pFlashInfoEx->region[i]) FlashRegion; 
+0

vì vậy, chỉ cần FlashInfoEx flashInfo sẽ không hoạt động sau đó. Cảm ơn. – Marcelo

1

Các interace mà bạn đang sử dụng đang sử dụng struct Hack. Điều này có nghĩa là bạn cần phải tự động phân bổ đủ lưu trữ cho cấu trúc như thể nó được khai báo với vùng là một mảng nhiều hơn 1 FlashRegion.

Đối với giao diện này, nó cần đủ không gian cho ít nhất và mảng dwNumRegionsFlashRegion s.

Thứ gì đó giống như offsetof(FlashInfoEx, region) + sizeof FlashRegion * n byte trong đó n là số mà bạn cần phải chuyển đến FMD_GetInfoEx hoặc bất kỳ chức năng nào bạn đang sử dụng.

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