स्टैक की दिशा की एक भ्रमित समस्या का पता लगाने के लिए मैं वालग्रिंड का उपयोग करता हूं।
नीचे दिए गए कोड को देखें, मैं जानना चाहता हूं कि ऑपरेटर "पी 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;
}
3 जवाब
जब आप 0x80
को p1
में जोड़ते हैं, तो आप एक पॉइंटर के साथ समाप्त होते हैं जो स्टैक फ्रेम में कहीं पहले इंगित करता है - संभवतः जहां main()
या पर्यावरण के तर्क संग्रहीत हैं। यही कारण है कि वालग्रिंड आपको चेतावनी नहीं देता - यह नहीं जानता कि आप स्टैक के उस हिस्से तक वैध पहुंच नहीं बना रहे हैं।
जब आप 0x80
को p2
से घटाते हैं, तो आपको एक पॉइंटर मिलता है जो %esp
से नीचे होता है। स्टैक का यह हिस्सा तार्किक रूप से अभी तक आवंटित नहीं किया गया है, यही वजह है कि वालग्रिंड आपको चेतावनी देता है।
नहीं, वह कोड अपरिभाषित व्यवहार देता है।
आपके ढेर में एक पूर्णांक होता है, और एक पूर्णांक सूचक और कुछ नहीं।
जब आप पॉइंटर 0x80 ints को मेमोरी (पिछले स्टैक) में आगे बढ़ाते हैं और वहां लिखते हैं कि आपने अपरिभाषित व्यवहार का आह्वान किया है, तो उसके बाद जो होता है उस पर आप अधिक विश्वास नहीं कर सकते।
यह निश्चित रूप से वहाँ सूचक को स्थानांतरित करने के लिए मान्य है, आप इसे कहीं भी ले जा सकते हैं, लेकिन वहां लिखने के लिए नहीं।
सबसे पहले, आपने हमें कोड दिया जो संकलित भी नहीं करता है।
फिर, किसी वस्तु से परे 128 पदों पर जाना अपरिभाषित व्यवहार है, चाहे आप वस्तु के पीछे जाएं या सामने। आपके उदाहरण में आपके -= 0x80
को आपको मूल सूचक पर वापस लाना चाहिए।
तो वालग्रिंड शायद दूसरे के साथ ठीक होना चाहिए, भले ही *p
के लिए आपका पहला असाइनमेंट पहले ही आपके स्टैक को क्रैश कर चुका हो।