स्टैक की दिशा की एक भ्रमित समस्या का पता लगाने के लिए मैं वालग्रिंड का उपयोग करता हूं।

नीचे दिए गए कोड को देखें, मैं जानना चाहता हूं कि ऑपरेटर "पी 1 + = 0x80; * पी 1 = 1" मान्य क्यों है और ऑपरेटर "पी 2 - = 0x80; * पी 2 = 1" वालग्रिंड के अनुसार अमान्य है?

मुझे लगता है कि ओएस के अनुसार स्टैक में सभी चर आवंटित किए गए हैं, और यह निचले पते तक बढ़ रहा है, इसलिए मुझे लगता है कि "- =" मान्य है और "+ =" अमान्य है क्योंकि यह तुलना में बड़ा हो सकता है स्टैक के शीर्ष पर जो स्टैक सीमा में नहीं हो सकता है।

#include <stdlib.h>

int main()
{
    int a;
    int *p1 = &a;
    p1 += 0x80;
    int *p2 = &a;
    *p1 = 1;
    p2 -= 0x80;
    *p2 = 1;
    return EXIT_SUCCESS;
}
0
xunzhang 16 नवम्बर 2011, 21:07
साबित करना चाहते हैं कि एंडर्स सही है - मेरा सुझाव है कि 0x80 के बजाय +/- 2 कोशिश करें - जो मुख्य :-) के भीतर कुछ कचरा करना चाहिए।
 – 
Adrian Cornish
16 नवम्बर 2011, 21:14
1
सिर्फ इसलिए कि वालग्रिंड एक ऑपरेशन के बारे में शिकायत नहीं करता है इसका मतलब यह नहीं है कि ऑपरेशन मान्य है।
 – 
interjay
16 नवम्बर 2011, 21:15

3 जवाब

सबसे बढ़िया उत्तर

जब आप 0x80 को p1 में जोड़ते हैं, तो आप एक पॉइंटर के साथ समाप्त होते हैं जो स्टैक फ्रेम में कहीं पहले इंगित करता है - संभवतः जहां main() या पर्यावरण के तर्क संग्रहीत हैं। यही कारण है कि वालग्रिंड आपको चेतावनी नहीं देता - यह नहीं जानता कि आप स्टैक के उस हिस्से तक वैध पहुंच नहीं बना रहे हैं।

जब आप 0x80 को p2 से घटाते हैं, तो आपको एक पॉइंटर मिलता है जो %esp से नीचे होता है। स्टैक का यह हिस्सा तार्किक रूप से अभी तक आवंटित नहीं किया गया है, यही वजह है कि वालग्रिंड आपको चेतावनी देता है।

0
caf 17 नवम्बर 2011, 07:13

नहीं, वह कोड अपरिभाषित व्यवहार देता है।

आपके ढेर में एक पूर्णांक होता है, और एक पूर्णांक सूचक और कुछ नहीं।

जब आप पॉइंटर 0x80 ints को मेमोरी (पिछले स्टैक) में आगे बढ़ाते हैं और वहां लिखते हैं कि आपने अपरिभाषित व्यवहार का आह्वान किया है, तो उसके बाद जो होता है उस पर आप अधिक विश्वास नहीं कर सकते।

यह निश्चित रूप से वहाँ सूचक को स्थानांतरित करने के लिए मान्य है, आप इसे कहीं भी ले जा सकते हैं, लेकिन वहां लिखने के लिए नहीं।

7
AndersK 16 नवम्बर 2011, 21:15

सबसे पहले, आपने हमें कोड दिया जो संकलित भी नहीं करता है।

फिर, किसी वस्तु से परे 128 पदों पर जाना अपरिभाषित व्यवहार है, चाहे आप वस्तु के पीछे जाएं या सामने। आपके उदाहरण में आपके -= 0x80 को आपको मूल सूचक पर वापस लाना चाहिए।

तो वालग्रिंड शायद दूसरे के साथ ठीक होना चाहिए, भले ही *p के लिए आपका पहला असाइनमेंट पहले ही आपके स्टैक को क्रैश कर चुका हो।

0
Jens Gustedt 16 नवम्बर 2011, 21:20