2009-09-08 25 views
5

Estoy tratando de entender este concepto: Tengo una definición de tamaño fijo:matrices dentro de estructuras en C

(de 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; 

este FlashRegion estructura, se utiliza en esta otra estructura: (a partir de: 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; 

El problema es que puede tener un número variable de FlashRegions dentro de un FlashInfoEx. La función que estoy depuración hace esto en alguna parte del código:

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

Eso significa que copia una cantidad de regiones a pFlashInfoEx (que yo paso en la llamada de la función);

Por lo tanto, el código sobrescribirá la memoria si dwNumRegions es mayor que uno. Si ese es el caso, ¿Debería crear una FlashRegion [FIXED_SIZE] en mi código y de alguna manera colocar/sobrescribir en FlashInfoEx-> region? ¿Cómo puedo hacer eso?

Gracias, Marcelo

Respuesta

6

El concepto es FlashRegion mientras que se parece a una estructura de tamaño fijo, en realidad es dinámicamente tamaño. La magia se realiza en la asignación de la estructura - en lugar de llamar (FlashRegion*)malloc(sizeof(FlashInfoEx)) o new FlashRegion, se llama algo así como (FlashRegion*)malloc(sizeof(FlashInfoEx)+sizeof(FlashRegion)*(numRegions-1))

+1

Wow, ustedes son rápidos aquí! Entonces, eso implica que la región siempre debe ser el último miembro de la estructura ¿verdad? Dependiendo del compilador, ¿no es esto un riesgo? – Marcelo

+0

Al definir las estructuras para poder interactuar con cualquier API, debe ser capaz de definir el diseño exacto de la memoria de la estructura. Creo que el estándar requiere que los miembros de la estructura se ordenen en el orden especificado, pero no especifica la alineación. En la práctica, todos los compiladores también proporcionan control de alineación. – Suma

+1

Sí, la región debe ser la última. ¿Riesgo? Solo en el sentido de que C en sí es arriesgado.De hecho, así es como se pretendía usar el lenguaje. Hay una razón por la que los lenguajes modernos lo hacen imposible, pero eso no rompe de manera retroactiva el patrón de diseño del kit de herramientas C89 y C90. – DigitalRoss

2

Este es un lenguaje bastante común C de estructuras de tamaño variable. Con el fin de hacer que esto funcione, es necesario asegurarse de que asignar memoria suficiente para el tamaño de la matriz que desea, por lo general algo así como

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

este interactúa mal con intentar utilizar 'nuevo' en C++; usted tiene que asignar la memoria manualmente:

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

entonces, simplemente FlashInfoEx flashInfo no funcionará entonces. Gracias. – Marcelo

1

El interace que está utilizando está utilizando la estructura piratear. Esto significa que debe asignar dinámicamente de forma manual suficiente espacio de almacenamiento para la estructura como si se hubiera declarado con región como una matriz de más de 1 FlashRegion.

Para esta interfaz, necesita espacio suficiente para al menos una matriz de dwNumRegionsFlashRegion s.

Algo como offsetof(FlashInfoEx, region) + sizeof FlashRegion * n bytes donde n es un número que debe pasar posteriormente al FMD_GetInfoEx o la función que esté utilizando.

Cuestiones relacionadas