5

मुझे एक अजीब स्थिति है। मैं अपने कैमरा प्रबंधन सॉफ्टवेयर में 10+ साल पुराना पीसीआई कैमरा डिवाइस एसडीके लागू करने की कोशिश कर रहा हूं। मैनिफैक्चरर अब व्यवसाय में नहीं है और मुझे आधिकारिक सहायता पाने का कोई मौका नहीं है। तो मैं यहां हूं, मेरी बदसूरत समस्या में कुछ मदद की तलाश में हूं।विजुअल स्टूडियो संस्करणों के बीच अलग-अलग मेमोरी व्यवहार

एसडीके Visual Studio 6.0 नमूने के साथ आता है। फ़ाइलों में से एक में एक संरचना है जो नीचे की तरह एक बाइट सरणी के साथ समाप्त होती है;

typedef struct AVData { 
    ... 
    BYTE audioVideoData[1]; 
}AVDATA, *PAVDATA; 

लेकिन यह एक बाइट आवंटित बाइट सरणी के लिए पर्याप्त वीडियो फ्रेम और अजीब प्राप्त करता है, यह विजुअल स्टूडियो 6.0 संस्करण के साथ ठीक काम करता है। अगर मैं इसे विजुअल स्टूडियो 2005/2008/2010 के साथ आज़माता हूं, तो मुझे Memory Access Violation त्रुटि संदेश मिलना शुरू हो जाता है जो वास्तव में समझ में आता है क्योंकि बाद में एक निश्चित आकार सरणी में स्थान आवंटित करना संभव नहीं है, नहीं? लेकिन वीएस 6.0 के साथ एक ही कोड ठीक चलाता है ?! यह शायद कंपाइलर या सी ++ रनटाइम मतभेदों के कारण होता है लेकिन मुझे इस विषय पर बहुत अनुभवी नहीं है, इसलिए मेरे लिए कुछ कारण बता देना मुश्किल है।

मैंने आकार को आकार की अधिकतम अपेक्षित बाइट्स में बदलने की कोशिश की;

typedef struct AVData { 
    ... 
    BYTE audioVideoData[20000]; 
}AVDATA, *PAVDATA; 

यह काम कर पाने लेकिन समय-समय पर मैं जब पुस्तकालय की डिकोडर वस्तु नष्ट करने की कोशिश स्मृति पहुँच उल्लंघन समस्याओं पाने में मदद की।

इसमें कुछ निश्चित रूप से गलत है। मेरे पास एसडीके के स्रोत कोड नहीं हैं, केवल डीएलएल, लिब और हेडर फाइलें हैं। मेरे प्रश्न हैं:

1) क्या यह विजुअल स्टूडियो 6.0 संस्करण में एक निश्चित आकार सरणी में स्थान आवंटित करने के लिए वास्तव में कानूनी है?

2) क्या कोई भी संभावित तरीका (एक कंपाइलर विकल्प इत्यादि) है जो एक ही कोड को नए वीएस संस्करण/सी ++ रनटाइम्स के साथ काम करने के लिए करता है?

3) चूंकि हेडर फ़ाइल को संपादित करने का मेरा कामकाज एक बिंदु तक काम करता है लेकिन अभी भी समस्याएं हैं, तो क्या आप इस समस्या को हल करने के लिए कोई बेहतर तरीका जानते हैं?

+0

मुझे लगता है कि समस्या कहीं और होनी चाहिए। सरणी का आकार यहां कोई समस्या नहीं होनी चाहिए, यह ऊपरी बाध्य होने का इरादा नहीं है। – BlueWanderer

+2

इसे एक लचीला सरणी कहा जाता है: http://stackoverflow.com/questions/5478706/flexible-array-member-c99-inside-a- संरचना –

+0

लेकिन फिर हमें मेमोरी एक्सेस उल्लंघन क्यों मिलता है? अगर मैं इस संरचना से एक नई वस्तु बना देता हूं, तो इसे 1 (+ संरचना संरचनाओं के बाकी हिस्सों) के आकार के साथ नहीं बनाया जाएगा? तो, हम बाद में ऑडियोविडियोडाटा सरणी में एक से अधिक बाइट कैसे स्टोर कर सकते हैं? क्या एक निश्चित आकार सरणी में स्मृति को पुन: आवंटित करना संभव है? चूंकि यह वीएस 6.0 संस्करण के साथ काम करता है, यह पहले संभव हो सकता है लेकिन वीएस 2005+ के बारे में क्या? –

उत्तर

3

आईआईआरसी आकार में परिवर्तनीय संरचना बनाने के लिए एक पुरानी चाल है।

पर विचार

struct { 
    int len; 
    char name[1]; 
} s; 

'नाम' अब चर लंबाई का हो सकता है अगर उचित आवंटन किया जाता है और यह क्रमिक रूप से स्मृति में बाहर रखी किया जाएगा:

char* foo = "abc"; 
int len = strlen(foo); 

struct s* p = malloc(sizeof(int) + len + 1); 

p->len = len; 
strcpy(p->name, foo); 

मुझे लगता है कि इसके बाद के संस्करण चाहिए दृश्य स्टूडियो के नए संस्करणों में भी ठीक काम करें, शायद यह पैकिंग का मामला है, क्या आपने बाइट सीमाओं पर structs प्राप्त करने के लिए #pragma पैक (1) किया है? मुझे पता है कि वीएस 6 ने इसे डिफ़ॉल्ट रूप से किया था।

+0

यहां तक ​​कि आपके उत्तर ने मेरी समस्या को हल नहीं किया है जिसमें प्रगति चाल शामिल है, आपका उत्तर सही है और इस समय मेरी समस्या असफल हो रही है। –

+0

यदि मैं आप थे तो मैं एक बहुत बड़ा बफर के साथ प्रयास करता हूं, 10 साल पहले से बहुत कुछ हुआ, खासकर गति। शायद संरचना के साथ असंबद्ध कुछ अन्य मुद्दा है। यदि बफर बढ़ाना स्मृति एक्सेस त्रुटियों को कम करता है तो आप इसके बजाय कुछ समय त्रुटि पर हो सकते हैं। –

3

इस तरह की सी संरचना में एक-तत्व सरणी का अर्थ यह है कि आकार रनटाइम तक अज्ञात है। (विंडोज़ उदाहरण के लिए, BITMAPINFO देखें।)

आमतौर पर, कुछ अन्य जानकारी (संभावित रूप से संरचना में) होगी जो आपको बताती है कि बफर को कितना बड़ा होना चाहिए।आप इन में से एक सीधे आवंटित कभी नहीं होगा, लेकिन इसके बजाय स्मृति के सही आकार ब्लॉक का आवंटन, तो यह डाली:

int size = /* calculate frame size somehow */ 
AVDATA * data = (AVDATA*) malloc(sizeof(AVDATA) + size); 
// use data->audioVideoData 
1

कोड लगभग निश्चित रूप से किसी तरह से अपरिभाषित व्यवहार दिखाता है, और वहाँ छोड़कर इसे ठीक करने के कोई रास्ता नहीं है एसडीके के इंटरफ़ेस या स्रोत कोड को ठीक करने के लिए। चूंकि यह अब व्यवसाय में नहीं है, यह असंभव है।

+0

तकनीकी रूप से, आप सही हैं - यह यूबी है। वास्तव में, संरचना हैक काफी लंबे समय तक काफी आम है कि जब आप इसे "सही" उपयोग करते हैं तो अप्रत्याशित परिणाम प्राप्त करने की संभावना अनिवार्य रूप से nonexistent हैं। सी 99 के बाद से अधिकांश कंपाइलरों के साथ बदलने की संभावना नहीं है और नए इसे "लचीला सरणी सदस्य" के रूप में आशीर्वाद देते हैं। –

+0

मुझे नहीं लगता कि यह उत्तर संदर्भ में समझ में आता है। "यूबी" प्रतिबंधों को हटा देता है कि एक मनमानी संकलक इसके साथ कैसे निपट सकता है। लेकिन हम जानते हैं कि लाइब्रेरी को वीसी 6 के साथ संकलित किया गया है, और कभी भी किसी अन्य कंपाइलर के साथ संकलित नहीं किया जाएगा, इसलिए व्यवहार पहले ही पत्थर में स्थापित है। – MSalters

संबंधित मुद्दे