2011-05-29 11 views
5

मैं हस्ताक्षर के साथ एक समारोह है:रिटर्न स्टेटमेंट के बाद यह परिवर्तनीय परिवर्तन क्यों होगा?

int exe(int stack[][STACKSIZE], int sp[], int reg[][REGISTERSIZE], int next_instruct[], 
     int next_inst[], int cur_proc, int *terminate); 

यह के अंतिम दो पंक्तियों है:

printf("TWO cur_proc: %d\n",cur_proc); 
return NORMAL; 

और इस तरह कहा जाता है:

printf("ONE cur_proc: %d\n",cur_proc); 
msg = exe(stack,sp,reg, next_instruct, next_instruct, cur_proc, &terminate); 
printf("THREE cur_proc: %d\n",cur_proc); 

और मैं में गुजर रहा cur_proc जिसे exe() के अंदर "केवल पढ़ने के लिए" माना जाता है (यह मूल्य द्वारा पारित किया जाना चाहिए)। exe() के अंदर मेरी सामग्री करो।

और मेरे उत्पादन है:

ONE cur_proc: 1 
TWO cur_proc: 1 
THREE cur_proc: -1 

यह मेरे लिए बहुत भ्रामक है के रूप में मैं किसी भी कारण से कि यह संभव एक नकारात्मक एक साथ ओवरराइट किया जा सकता है नहीं देख सकता।

इस अजीब व्यवहार के लिए संभावित कारण क्या है?

+0

जब cur_proc अपना मान बदलता है तो यह देखने का एक आसान तरीका है कि कॉन्स्ट के साथ तर्क घोषणा को उपसर्ग करना है। कंपाइलर उस त्रुटि को फेंक देगा जहां आप अपना मूल्य बदलते हैं। –

+0

मैंने पहले कोशिश की। कोई त्रुटि नहीं थी क्योंकि जहां तक ​​संकलक समझता है कि यह बदल नहीं रहा है। –

+0

फिर अपने प्रोग्राम को [valgrind] (http://valgrind.org) के साथ चलाएं। आपके कार्यक्रम का एक और हिस्सा शायद आपके ढेर को दूषित कर रहा है। –

उत्तर

4

आप शायद सरणी में से किसी एक की सीमा के बाहर लिख रहे हैं।

फ़ंक्शन के अंदर, आप मूल चर पर नहीं, कॉलिंग फ़ंक्शन में चर की एक प्रति देख रहे हैं। इसलिए, फ़ंक्शन के अंदर printf() आपको यह नहीं बताता है कि कॉलिंग फ़ंक्शन में मान कब दूषित हो गया है।

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

यदि आप कॉल करना चाहते हैं तो कॉलिंग फ़ंक्शन में cur_proc में परिवर्तन फ़ंक्शन में होता है, तो फ़ंक्शन में cur_proc पर पॉइंटर को पास करें - साथ ही या मूल्य के बजाय - और पॉइंटर के माध्यम से मान प्रिंट करें ।

+0

यही वह है। ढेर कार्य उनकी सीमाओं के बाहर लिख रहे हैं। Cur_proc को पॉइंटर को देखकर इसे साफ़ कर दिया गया। –

3

यदि आपके exe फ़ंक्शन के भीतर कोड पारित होने वाले सरणी में से किसी एक में अमान्य स्थान पर डेटा लिखता है, तो स्टैक दूषित हो सकता है जो संभावित रूप से स्थानीय चर के मूल्य को स्टैक तक बढ़ा सकता है (अन्य बुरी चीजों के साथ))।

फ़ंक्शंस परिप्रेक्ष्य से अपने चर की केवल पढ़ने वाली प्रकृति को देखते हुए, या तो यह हो रहा है या कोई अन्य धागा cur_proc के मान को संशोधित कर रहा है - यदि आप थ्रेडिंग के साथ झुकाव नहीं कर रहे हैं तो पूर्व में अधिक संभावना है।

अधिकांश डिबगर्स आपको "स्मृति में किसी विशेष पते पर मूल्य बदलने" पर ब्रेकपॉइंट रखने की अनुमति देते हैं। यदि आपको cur_proc का पता मिलता है और जब इस पते पर मूल्य बदल जाता है तो आपको अपना अपराधी मिलना चाहिए।

+0

यह मेरा पहला विचार भी था, लेकिन मैंने इसे पहले कभी नहीं देखा है। मैं इसे कैसे डीबग करूं?(यह गैर-थ्रेडेड बीटीडब्लू है) –

+0

अधिकांश डिबगर्स आपको "स्मृति में किसी विशेष पते पर मूल्य बदलने" पर ब्रेकपॉइंट रखने की अनुमति देते हैं। यदि आपको cur_proc का पता मिलता है और जब इस पते पर मूल्य बदल जाता है तो आपको अपना अपराधी मिलना चाहिए। –

+0

... ने कहा है कि, यदि आप डीबगर के आसपास अपना रास्ता नहीं जानते हैं तो निम्न तकनीक और सरल तरीका है जोनाथन लेफ्लर द्वारा उनकी प्रतिक्रिया में वर्णित है - विचार करने योग्य है। –

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