2009-09-08 16 views
5

Özür: bir sabit boyutlu ifade edecektir:Diziler Bu kavramı anlamak için mücadele

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

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

bu FlashRegion yapı, bu başka bir yapı kullanılır: (dan: 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; 

sorun, bir FlashInfoEx içinde FlashRegions değişken bir sayı olabilir. Özür hatalrı bu bir yere yapar fonksiyonu:

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

anlamına geliyor pFlashInfoEx (I işlev çağrısı içinde geçer ki) kopyalamadan bölgelerin bir miktarı;

Yani, dwNumRegions bir taneden büyükse, kod belleğin üzerine yazacaktır. Bu durumda, kodumda bir FlashRegion [FIXED_SIZE] oluşturmalı ve FlashInfoEx-> bölgesinde bir yer/üzerine yazmalı mıyım? Bunu nasıl yaparım?

sayesinde Marcelo

cevap

6

kavram FlashRegion sabit boyutlu bir yapı gibi görünüyor ederken, aslında dinamik büyüklükte olmasıdır. yapıyı tahsis ederken sihirli yapılır - yerine (FlashRegion*)malloc(sizeof(FlashInfoEx)) veya new FlashRegion arayarak, sen (FlashRegion*)malloc(sizeof(FlashInfoEx)+sizeof(FlashRegion)*(numRegions-1))

+1

Wow, sizler burada hızlısınız! Yani, bu, bölgenin her zaman yapı hakkının son üyesi olması gerektiği anlamına mı geliyor? Derleyiciye bağlı olarak, bu bir risk değil mi? – Marcelo

+0

Herhangi bir API ile etkileşime girebilecek yapıları tanımlarken, yapının tam olarak bellek düzenini tanımlayabilmeniz gerekir. Bence standart, yapı elemanlarının belirtilen sırada sipariş edilmesini gerektirir, ancak hizalamayı belirtmez. Pratikte tüm derleyiciler hizalama kontrolünü de sağlarlar. – Suma

+1

Evet, bölge son olmalı. Risk? Sadece C'nin kendisi riskli olduğu için.Bu aslında dilin nasıl kullanılacağıdır. Modern dillerin bunu imkansız kılması için bir neden var, ancak bu, tasarım modelini C89 ve C90 araç setinden geriye doğru yormuyor. – DigitalRoss

2

Bu variably yapılar için oldukça yaygın bir C deyim olduğu gibi bir şey diyoruz. bu işi yapmak için, size istediğiniz dizi boyutu,

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

bu C++ 'yeni' kullanmaya çalışıyor ile kötü etkileşim gibi genellikle bir şey için yeterli bellek ayrılamadı sağlamak için gereken;

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

Yani, sadece FlashInfoEx flashInfo o zaman çalışmayacak. Teşekkürler. – Marcelo

1

Eğer yapı kesmek kullanabiliyorken InterACE: manuel bellek tahsis etmek gerekir. Bu, yapı için, 1 FlashRegion'dan daha fazla bir dizi olan bir bölge olarak bildirilmiş gibi, el ile dinamik olarak depolama için yeterli depolama alanı ayırmanız gerektiği anlamına gelir.

Bu arabirim için, en az dwNumRegionsFlashRegion s dizisi için yeterli alan olması gerekir.

n'un FMD_GetInfoEx olduğu yere veya FMD_GetInfoEx numarasına geçmeniz gereken bir sayı olduğu offsetof(FlashInfoEx, region) + sizeof FlashRegion * n bayt gibi bir şey.