2009-09-08 9 views
5

मैं इस अवधारणा को समझने के लिए संघर्ष कर: मैं एक निश्चित आकार परिभाषा है:सरणी

(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, यह एक और struct में प्रयोग किया जाता है: (से: 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; 

समस्या है, मैं एक FlashInfoEx अंदर FlashRegions के परिवर्तनशील हो सकता है। समारोह है कि मैं डिबगिंग कोड में यह कहीं करता है:

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

इसका मतलब है कि यह pFlashInfoEx (है कि मैं समारोह के कॉल में पास) के लिए प्रतियां क्षेत्रों की राशि;

तो, अगर कोड एक से बड़ा होता है तो कोड स्मृति को ओवरराइट करेगा। यदि ऐसा है, तो क्या मुझे अपने कोड में FlashRegion [FIXED_SIZE] बनाना चाहिए और किसी भी तरह FlashInfoEx-> क्षेत्र में स्थान/ओवरराइट करना चाहिए? मैं उसको कैसे करू?

धन्यवाद, मार्सेलो

उत्तर

6

अवधारणा FlashRegion एक निश्चित आकार संरचना की तरह लग रहा है, जबकि, यह वास्तव में गतिशील रूप से आकार है। जादू जब संरचना का आवंटन किया जाता है - के बजाय (FlashRegion*)malloc(sizeof(FlashInfoEx)) या new FlashRegion बुलाने की, आप की तरह (FlashRegion*)malloc(sizeof(FlashInfoEx)+sizeof(FlashRegion)*(numRegions-1))

+1

वाह, तुम लोग यहाँ तेज़ हो! तो, इसका तात्पर्य है कि क्षेत्र हमेशा संरचना के अंतिम सदस्य होना चाहिए? कंपाइलर के आधार पर, क्या यह जोखिम नहीं है? – Marcelo

+0

किसी भी एपीआई के साथ बातचीत करने में सक्षम होने के लिए structs को परिभाषित करते समय आपको संरचना के सटीक मेमोरी लेआउट को परिभाषित करने में सक्षम होना चाहिए। मुझे लगता है कि मानक को निर्धारित क्रम में स्ट्रक्चर सदस्यों को आदेश देने की आवश्यकता है, लेकिन यह संरेखण निर्दिष्ट नहीं करता है। अभ्यास में सभी कंपाइलर संरेखण नियंत्रण भी प्रदान करते हैं। – Suma

+1

हां, क्षेत्र अंतिम होना चाहिए। जोखिम? केवल इस अर्थ में कि सी स्वयं जोखिम भरा है।यह वास्तव में भाषा का उपयोग करने का इरादा था। एक कारण यह है कि आधुनिक भाषाएं इसे असंभव बनाती हैं, लेकिन यह सी 8 9 और सी 0 9 टूलकिट से डिजाइन पैटर्न को पीछे हटाना नहीं करती है। – DigitalRoss

2

यह variably आकार संरचनाओं के लिए एक बहुत ही आम सी मुहावरा है कुछ कहते हैं। आदेश में इस काम करने के लिए, आप सरणी आकार आप चाहते हैं, आम तौर पर की तरह

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

इस का उपयोग करने के 'नए' C++ कोशिश कर के साथ बुरी तरह से सूचना का आदान प्रदान के लिए कुछ के लिए पर्याप्त स्मृति को आबंटित सुनिश्चित करने के लिए की जरूरत है;

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

तो, बस FlashInfoEx FlashInfo तब काम नहीं करेगा। धन्यवाद। – Marcelo

1

interace है कि आप प्रयोग कर रहे हैं उपयोग कर रहा है struct हैक: आप मैन्युअल रूप से स्मृति को आबंटित करने की है। इसका मतलब है कि आपको संरचना के लिए पर्याप्त रूप से गतिशील रूप से आवंटित करने की आवश्यकता है जैसे कि यह क्षेत्र को 1 FlashRegion से अधिक की सरणी के रूप में घोषित किया गया हो।

इस इंटरफ़ेस के लिए, इसे कम से कम dwNumRegionsFlashRegion एस के लिए पर्याप्त स्थान होने की आवश्यकता है।

offsetof(FlashInfoEx, region) + sizeof FlashRegion * n बाइट्स जैसे कुछ n एक संख्या है जिसे आपको बाद में FMD_GetInfoEx या जो भी कार्य आप उपयोग कर रहे हैं उसे पास करने की आवश्यकता है।