2009-02-28 14 views
13

यह देखते हुए कि सभी आदिम डेटा प्रकारों और वस्तुओं में स्मृति आवंटित है, यह इन प्रकारों के पॉइंटर्स की कल्पना करना आसान है।फ़ंक्शन पॉइंटर्स वास्तव में कहां इंगित करते हैं?

लेकिन फ़ंक्शन पॉइंटर्स वास्तव में कहां इंगित करते हैं? यह देखते हुए कि निर्देश मशीन कोड में परिवर्तित हो जाते हैं और स्मृति में रहते हैं, क्या हमें लगता है कि वे कार्य निर्देशों की शुरुआत के अनुरूप स्मृति स्थान को इंगित करते हैं?

अवैध स्मृति पहुंच के कारण हमें पॉइंटर्स में कई त्रुटियों का सामना करना पड़ता है। क्या यह मामला है कि त्रुटियां तब होती हैं जब फ़ंक्शन पॉइंटर्स निर्देश स्मृति की बजाय डेटा मेमोरी को इंगित करते हैं?

+0

क्या आप अपने फ़ंक्शन पॉइंटर्स या अन्य पॉइंटर्स पर अवैध मेमोरी एक्सेस देख रहे हैं? –

+0

अवैध स्मृति पहुंच के कारण "हमें पॉइंटर्स में कई त्रुटियों का सामना करना पड़ता है" का क्या अर्थ है? ये त्रुटियां कैसे होती हैं? ये त्रुटियां क्या हैं? –

+0

@ स्टेव नहीं @ एसएलओटी मैं उन त्रुटियों का जिक्र कर रहा था जब हम कुछ कचरे के लिए int * प्रारंभ करते हैं जो सुरक्षित स्मृति पता है। –

उत्तर

29

फ़ंक्शन पॉइंटर भी स्मृति में इंगित करता है, केवल अंतर यह है कि डेटा के बजाय उस स्मृति स्थान पर निष्पादन योग्य कोड है।

यदि आप डेटा निष्पादित करने का प्रयास करते हैं तो कई प्लेटफॉर्म पर (जैसे नियमित मेमोरी) आप क्रैश हो जाएंगे या अपवाद का कारण बनेंगे। इसे डेटा निष्पादन रोकथाम के रूप में जाना जाता है - मैलवेयर द्वारा रखे जा सकने वाले कोड को अनजाने में चलने वाले अनुप्रयोगों को रोकने के लिए एक सुरक्षा उपाय।

+0

और मुझे लगता है कि निष्पादन शुरू करने से पहले, संबंधित फ़ंक्शन फ्रेम प्रारंभ किया गया है। उदाहरण के लिए, बनाए गए विशिष्ट ऑपरेंड स्टैक और स्थानीय चर सरणी (पास किए गए तर्कों के साथ) पर कॉल करें। – zgulser

4

यह एक कोड सूचक है। यह फ़ंक्शन के पते को इंगित करता है। जैसा कि आपने वर्णन किया है यह अनिवार्य रूप से है। और हां, यदि आपके पास पॉइंटर्स हैं जो आपको उम्मीद नहीं करते हैं, तो आपको समस्याएं होगी।

-3

अच्छी तरह से मुझे यकीन नहीं है कि उन कार्यों पर विचार निर्देश (एडीडी, एसयूबी, जेएमपी) हैं और उनमें से प्रत्येक में हेक्साडेसिमल मान हैं, मेरा मानना ​​है कि आप फ़ंक्शन को बदल नहीं पाएंगे बल्कि केवल जेएमपी निर्देश()। ..

+1

यदि आप जेएमपी निर्देश में बदलाव कर रहे हैं, तो आपके पास स्व-संशोधित कोड है, जिसे आमतौर पर काला जादू माना जाता है। फ़ंक्शन पॉइंटर्स अन्य पॉइंटर्स की तरह हैं - रैम में संग्रहीत पता; जेएमपी कार्यक्रम में संकलित डेटा के बजाय चर से यह लक्ष्य प्राप्त करता है। –

+0

मुझे लगता है कि कुछ सीपीयू जो इस तरह से सभी पॉइंटर्स करते हैं, उदाहरण के लिए "पॉइंटर" कोड में एक मूल्य है, बहुत सरल पीआईसी और डीएसपी। –

+0

मुझे यह नहीं मिला, विचार की मेरी रेखा में दोष कहां है? – Diones

2

फ़ंक्शन पॉइंटर्स स्मृति में address of the function पर इंगित करता है।

फ़ंक्शन पॉइंटर्स आमतौर पर असाइन किए जाने के तरीके के आधार पर, यदि आप उन्हें डेटा स्थान पर इंगित करते हैं तो मुझे आश्चर्य होगा। वे आम तौर पर एक वैध कार्य के अलावा कहीं भी इंगित करने के लिए कास्ट नहीं होते हैं। यदि आप उन्हें बहुत कास्टिंग कर रहे हैं, तो यह एक समस्या हो सकती है। अधिक संभावना है कि यह है कि आप जिस फ़ंक्शन को पास कर रहे हैं वह गलत है।

2

एक फ़ंक्शन पॉइंटर में फ़ंक्शन का पता होता है - जो भी किसी दिए गए सिस्टम के लिए है। आप अप्रत्यक्ष रूप से फ़ंक्शन को कॉल करने के लिए इसका उपयोग कर सकते हैं, आप फ़ंक्शन पॉइंटर मान असाइन और तुलना कर सकते हैं। आप फ़ंक्शन पॉइंटर को किसी अन्य पॉइंटर-टू-फ़ंक्शन प्रकार में भी परिवर्तित कर सकते हैं, और बहुत आगे।

फ़ंक्शन पॉइंटर को कार्यान्वित करने के लिए एक कंपाइलर के लिए सबसे सरल तरीका फ़ंक्शन का स्मृति पता है, और अधिकांश कंपाइलर इसे इस तरह से करते हैं, लेकिन भाषा मानक इसे निर्दिष्ट नहीं करता है। कुछ सिस्टम (मुझे लगता है कि आईबीएम का एएस/400 एक उदाहरण है) फंक्शन पॉइंटर्स में अतिरिक्त जानकारी स्टोर करें। एक कंपाइलर फिक्स्ड पॉइंटर्स को डिस्क्रिप्टर की एक तालिका में पूर्णांक इंडेक्स के रूप में कार्यान्वित कर सकता है, जब तक आवश्यक अर्थशास्त्र लागू हो।

फ़ंक्शन पॉइंटर को हटाना संभव नहीं है। फ़ंक्शन कॉल के लिए एक पॉइंटर की आवश्यकता होती है, फ़ंक्शन नाम नहीं, इसकी उपसर्ग अभिव्यक्ति के रूप में; यदि आप फ़ंक्शन नाम का उपयोग करते हैं, तो वह नाम पूरी तरह से एक सूचक में परिवर्तित हो जाता है (जहां तक ​​भाषा का संबंध है; जेनरेट किया गया मशीन कोड अलग हो सकता है)। इसलिए किसी प्रोग्राम के लिए यह पता लगाने के लिए कोई पोर्टेबल तरीका नहीं है कि फ़ंक्शन पॉइंटर्स में वास्तव में मेमोरी पते हैं या नहीं।

गैर portably, एक समारोह func दिया, आप की तरह कुछ कर सकते हैं:

printf("Address of func is %p\n", (void*)func); 

और आप शायद कुछ है कि एक स्मृति पते की एक मानव पठनीय प्रतिनिधित्व दिखाई देगा।लेकिन कड़ाई से बोलते हुए, फ़ंक्शन पॉइंटर के रूपांतरण का व्यवहार void* को भाषा द्वारा परिभाषित नहीं किया गया है, और यह कुछ सिस्टम पर काम नहीं कर सकता है।

आप पराक्रम भी unsigned char* करने के लिए एक समारोह सूचक बदलने और समारोह की मशीन कोड की जांच करने में सक्षम हो, लेकिन कहीं सी मानक द्वारा परिभाषित कुछ भी परे चला जाता है।

फ़ंक्शन पॉइंटर्स को अपारदर्शी मानों के रूप में पेश करना सबसे अच्छा है जो कुछ अनिर्दिष्ट तरीके से विशेष कार्यों को संदर्भित करते हैं।

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