2012-06-09 24 views
5

शायद यह एक नौसिखिया प्रश्न है, लेकिन क्या एक फ़ंक्शन को स्थानीय चर में पॉइंटर स्वीकार करने से रोकने के लिए सी/सी ++ में कोई तरीका है?स्थानीय पॉइंटर्स को रोकना

int* fun(void) 
{ 
int a; 
return &a; 
} 

संकलक एक चेतावनी है कि सूचक लौटाया नहीं जा सकता उत्पन्न करेगा:

इस कोड पर विचार करें। अब इस पर विचार करें:

int* g; 

void save(int* a) 
{ 
g = a; 
} 

void bad(void) 
{ 
int a; 
save(&a); 
} 

यह बिना किसी चेतावनी के संकलक के माध्यम से गुजर जाएगा, जो खराब है। क्या ऐसा होने से रोकने के लिए कोई विशेषता या कुछ है? अर्थात। कुछ ऐसा:

void save(int __this_pointer_must_not_be_local__ * a) 
{ 
g = a; 
} 

अग्रिम धन्यवाद अगर कोई जवाब जानता है।

+1

कोड समीक्षा? ... लिंट जैसे कोड प्रोफाइलर्स? –

+0

कोड समीक्षा, स्थिर विश्लेषण। जो आप पूछ रहे हैं वास्तव में बहुत जटिल है। –

+1

क्या होगा यदि मैं 'void f() {int b; बचाओ (&b);/* सामान */सेव (एनयूएलएल);} '? यह जरूरी नहीं है कि वैरिएबल" स्थानीय "है जो मायने रखता है; यह भी बुरा होगा। 'int * p = new int(); save (p); पी हटाएं; ' –

उत्तर

0

नहीं, कोई पॉइंटर से एक ढेर ऑब्जेक्ट में पॉइंटर को बताने के लिए कोई विश्वसनीय और पोर्टेबल तरीका नहीं है। घोषणात्मक रूप से इसे रोकने के लिए कोई रास्ता नहीं है, या तो।

हैक्स आपके विशिष्ट सिस्टम के मेमोरी लेआउट पर निर्भर हैं जो अनिश्चित व्यवहार का आह्वान करके रनटाइम पर काम करते हैं (उदाहरण के लिए this answer देखें), लेकिन यदि आप उन्हें आज़माते हैं तो आप स्वयं ही हैं।

+0

लेकिन यदि संकलक कैम स्थानीय पहचानकर्ता को वापस करने का प्रयास कर रहा है, और यदि ओपी के रूप में कोई विशेषता थी, तो संकलक एक चेतावनी उत्पन्न करने के लिए एक ही तर्क का उपयोग क्यों नहीं कर सकता? –

+0

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

+0

रिटर्न चेक से अलग कैसे है, जिसे लागू किया गया है? –

2

है डीबग बिल्ड के लिए कम से कम एक तरह से डिबग ढेर (डिफ़ॉल्ट) का उपयोग करते हुए:

//d:\Program Files\Microsoft Visual Studio ?\VC\crt\src\dbgint.h 
\#define nNoMansLandSize 4 
typedef struct _CrtMemBlockHeader 
{ 
    struct _CrtMemBlockHeader * pBlockHeaderNext; 
    struct _CrtMemBlockHeader * pBlockHeaderPrev; 
    char *      szFileName; 
    int       nLine; 
    size_t      nDataSize; 
    int       nBlockUse; 
    long      lRequest; 
    unsigned char    gap[nNoMansLandSize]; 
    /* followed by: 
    * unsigned char   data[nDataSize]; 
    * unsigned char   anotherGap[nNoMansLandSize]; 
    */ 
} _CrtMemBlockHeader; 
\#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1)) 

वहाँ एक आवंटन हैडर, जो खाई के साथ समाप्त होता है, इसलिए वहाँ बड़ी संभावना 0xFDFDFDFD किया जाएगा से पहले नहीं है सूचक - सही नहीं है, लेकिन मदद कर सकते हैं ...

if (\*((int\*)pointer-1) == 0xFDFDFD) { // stack pointer } 
संबंधित मुद्दे