2014-07-11 5 views
6

तक नहीं पहुंच सकता, मेरे पास एक सी ++ प्रोग्राम है जो फ्लेक्स/बायसन द्वारा उत्पन्न कुछ सी रूटीन को कॉल करता है।malloc() लौटने वाला पता जिसे मैं

जब मैं एक Windows 8.1 64-बिट मंच लक्षित करते हैं, मैं क्रम में निम्न अपवाद मारा:

YY_BUFFER_STATE yy_create_buffer(FILE *file, int size) 
{ 
    YY_BUFFER_STATE b; 
    b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state)); 
    if (! b) 
     YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); 
    b->yy_buf_size = size; // This access is what throws the exception 
} 

संदर्भ के लिए:

Unhandled exception at 0x0007FFFA70F2C39 (libapp.dll) in application.exe: 0xC0000005: 
Access violation writing location 0x000000005A818118. 

मैं कोड का निम्न भाग को यह अपवाद का पता लगाया , कोड (भी फ्लेक्स/बाइसन द्वारा उत्पन्न) में कहीं और, हमने:

typedef struct yy_buffer_state *YY_BUFFER_STATE; 
struct yy_buffer_state 
{ 
    FILE *yy_input_file; 
    char *yy_ch_buf; 
    char *yy_buf_pos; 
    yy_size_t yy_buf_size; 
    // ... other fields omitted, 
    // total struct size is 56 bytes 
} 

static void *yy_flex_alloc(yy_size_t size) 
{ 
    return (void *) malloc(size); 
} 

मैं ट्रेस malloc पर वापस कॉल करें और देखा कि malloc स्वयं 0x000000005A818118 पते पर लौट रहा है। मैंने errno भी चेक किया, लेकिन यह malloc पर कॉल के बाद सेट नहीं है।

मेरा प्रश्न है: malloc मुझे ऐसा पता क्यों देता है कि मेरे पास पहुंच नहीं है, और मैं इसे सही पता कैसे दे सकता हूं?

नोट: मैं केवल विंडोज 8.1 64-बिट में इस व्यवहार को देखता हूं। यह अन्य 32-बिट विंडोज संस्करणों के साथ-साथ विंडोज 7 32-बिट के साथ गुजरता है।

संकलन जानकारी:

// b = (YY_BUFFER_STATE) yy_flex_alloc(...) 
0007FFFA75E2C12 call yy_flex_alloc (07FFFA75E3070h) 
0007FFFA75E2C17 mov qword ptr [b],rax 
// if (! b) YY_FATAL_ERROR(...) 
0007FFFA75E2C1C cmp qword ptr [b],0 
0007FFFA75E2C22 jne yy_create_buffer+30h (07FFFA75E2C30h) 
0007FFFA75E2C24 lea rcx,[yy_chk+58h (07FFFA7646A28h)] 
0007FFFA75E2C2B call yy_fatal_error (07FFFA75E3770h) 
// b->yy_buf_size = size 
0007FFFA75E2C30 mov rax,qword ptr [b] 
0007FFFA75E2C35 mov ecx,dword ptr [size] 
0007FFFA75E2C39 mov dword ptr [rax+18h],ecx 

धन्यवाद: मैं दृश्य स्टूडियो 2012

का उपयोग कर यदि यह मदद करता है एक 64-बिट Windows 8.1 मशीन पर यह संकलन कर रहा हूँ, यहाँ disassembled कोड है!

+0

मैं इस खंड को कई बार फिर से चलाता हूं, 'मॉलोक' या तो "आवंटित" स्थान के पते के लिए '00000000 --------' या 'FFFFFFFF --------' देता है। –

+0

सबसे अधिक संभावना है कि, कोड के कुछ अन्य, असंबद्ध हिस्से ने ढेर को भ्रष्ट करने में कामयाब रहा है (उदाहरण के लिए एक ढेर-आवंटित बफर को ओवरराइंग करके)। जिस कोड को आप देख रहे हैं उसका हिस्सा निर्दोष शिकार है। –

+0

आपका प्रोग्राम ढेर भ्रष्टाचार परिदृश्य का अनुभव कर रहा है। आप इस आलेख पर पोस्ट का उल्लेख कर सकते हैं: http://stackoverflow.com/a/22074401/2724703 –

उत्तर

3

असली जवाब है:

आप दृश्य स्टूडियो में फ्लेक्स-उत्पन्न .c स्रोत संकलन कर रहे हैं, यह stdlib.h शामिल नहीं है (जहां mallocशून्य *) लौटने के रूप में परिभाषित और विजुअल स्टूडियो कुछ खुद परिभाषा है, जहां malloc रिटर्न पूर्णांक लेता है। (मुझे लगता है कि यह संगतता के कुछ प्रकार के लिए है)

दृश्य स्टूडियो प्रिंट:

'C4013 चेतावनी:' malloc 'अपरिभाषित; यह मानते हुए कि निर्वासन लौटने पूर्णांक ' sizeof (int) == 4, लेकिन 64 सिस्टम पर संकेत में मूल्यों अक्सर 4 बाइट से अधिक

तो अपने सूचक सिर्फ कम 4 बाइट के लिए काटा।

ऐसा लगता है कि यह समस्या केवल x64.c फ़ाइलों में दृश्य स्टूडियो बिट्स में दिखाई देती है।

तो, समाधान होगा - बस अपने आप से stdlib.h में शामिल हैं, या कुछ मैक्रो, जो stdlib.h जैसी फ्लेक्स-उत्पन्न स्रोत में नेतृत्व करेंगे परिभाषित करते हैं।

+0

मैं केवल कल्पना कर सकता हूं कि आपने मुझे इस जवाब के साथ कितने घंटे बचाए हैं। – Rafal

2

सामान्य परिस्थितियों में malloc() वैध, सुलभ स्मृति या अन्य के लिए एक सूचक वापस कर देगा। इसलिए, आपके लक्षण इंगित करते हैं कि malloc() एक अनिर्दिष्ट तरीके से व्यवहार कर रहा है। मुझे संदेह है कि, कुछ बिंदु पहले, आपके कार्यक्रम ने इसकी वैध स्मृति के बाहर लिखा था, जिससे मैलोक() द्वारा आंतरिक रूप से उपयोग की जाने वाली डेटा संरचनाओं को दूषित कर दिया गया था।

रन-टाइम मेमोरी विश्लेषण टूल के साथ आपकी प्रक्रिया की जांच करने से आपको इस मुद्दे के स्रोत की पहचान करने में मदद मिलनी चाहिए। [विंडोज के लिए स्मृति विश्लेषण उपकरणों पर सुझाव के लिए यह पोस्ट देखें: Is there a good Valgrind substitute for Windows?]

+0

धन्यवाद, यह एक अच्छा सुझाव है। जैसे ही मैं विंडोज 8 संगत रिसाव डिटेक्टर स्थापित कर सकता हूं, मैं इसे देख लूंगा ... हालांकि मैंने इस एप्लिकेशन के लिनक्स संस्करण पर वालग्रिंड चलाया था, और ऐसा कुछ भी संदिग्ध प्रतीत नहीं होता था। जब तक कोड का यह हिस्सा चलाया जाता है, तो मैंने केवल 4 बाइट खो दिए (लाइब्रेरी फ़ंक्शन के कारण जो मैं नहीं बदल सकता ...) –

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