2015-09-11 20 views
5

का पता लगाने

वहाँ एक रास्ता है tldr (डाली-टू-सूचक ऑपरेटर के साथ) ढेर चर पर हटाने के लिए, स्थिर कोड निम्नलिखित में त्रुटि पता लगाने के लिए बुला?

struct Foo 
{ 
    operator const int*() 
    { 
     return &data; 
    } 

    int data; 
}; 

int main() 
{ 
    Foo f; 
    delete f; 
} 

के बाद से वहाँ फू से एक रूपांतरण सिर्फ एक उपयोगकर्ता परिभाषित रूपांतरण युक्त शून्य करने के लिए * है, यह वास्तव में f पर delete कॉल करने के लिए अनुमति दी है।

अब कहानी

हमारे codebase में

, वहाँ स्यूडोकोड में deserialize तार का एक बहुत बेवकूफ तरीका था,

char * buff = bar.loadString(); 
use buff; 
delete buff; 

तरह से बदल गया था एक टेम्प्लेटेड लोड कार्य करने के लिए, है, इसलिए अब दिखता deserialize

bar.load(m_IntMember); 
bar.load(m_StringMember); 

लेकिन सभी घटनाओं की तरह loadString की (उनमें से एक बहुत कुछ किया गया था)

string buff; 
bar.load(buff); 
use buff; 

हम सभी जानते हैं क्या मानव त्रुटि पैदा कर सकता है, इसलिए स्थानों, जहां कोड को गलत तरीके से

string buff; 
bar.load(buff); 
use buff; 
delete buff;  //notice the delete 

तरह संशोधित किया गया था के बाद से हम एक सा गैर का उपयोग कर रहे हैं: मैन्युअल रूप से इस तरह परिवर्तित करने की थी string के मानक कार्यान्वयन यह वास्तव में एक overloaded const char * operator, जो void* जो हटाए जा सकते हैं करने के लिए casted जा सकता है ... है

मैं संकलन समय पर इन त्रुटियों के सभी को पकड़ने के लिए चाहते हैं (हम कस्टम उच्च प्रदर्शन alloca है Tors, रनटाइम पर हां, तो यह भ्रष्ट स्मृति करने के लिए आसान किसी भी रनटाइम त्रुटि के बिना है)

मैं, वैश्विक हटाने ऑपरेटर को स्वीकार const char* मैं अस्थायी रूप से string से ऑपरेटर को नष्ट नहीं हटा सकते क्योंकि यह भारी प्रयोग किया जाता है की घोषणा नहीं कर सकते हैं तो यह संकलन करने में असमर्थ है इसके बिना (मैं सभी त्रुटियों से त्रुटि का वर्णन नहीं कर सकता, क्योंकि एमएसवीसी कुछ निश्चित त्रुटियों तक पहुंचने पर संकलन रोकता है)

मैं क्या कर सकता हूं?

+0

यह भेद करने के लिए संभव नहीं है। बल्कि एक स्मार्ट सूचक का प्रयोग करें। –

+0

'कॉन्स्ट char *' 'void *' के लिए पूरी तरह से परिवर्तनीय नहीं है क्योंकि यह 'const'-ness खो देता है। यह 'कॉन्स्ट शून्य *' के लिए पूरी तरह से परिवर्तनीय है, लेकिन यह 'हटाने' के लिए कानूनी तर्क नहीं होना चाहिए। क्या आप स्पष्ट रूप से कहीं कास्टिंग कर रहे हैं? – jamesdlin

+0

@jamesdlin यह ठीक से संकलित करता है जब मैं 'const int *' को वापस करने के लिए उदाहरण संशोधित करता हूं http://ideone.com/aL23m2 – relaxxx

उत्तर

2

यह यह करने के लिए लगता है:

#include <iostream> 

struct Foo 
{ 
    Foo() : data(42) {} 

    operator const int*() 
    { 
     return &data; 
    } 

    int data; 

    struct AmbiguousPointerConversion {}; 
    private: operator AmbiguousPointerConversion *() { 
     throw "hi"; 
    } 
}; 

int main() 
{ 
    Foo f; 
    const int *p = f; 
    std::cout << *p << '\n'; 
    delete f; 
} 

जी ++ के साथ इस संकलन मुझे देता है:

try.cc: In function ‘int main()’: 
try.cc:25:12: error: ambiguous default type conversion from ‘Foo’ 
    delete f; 
      ^
try.cc:25:12: note: candidate conversions include ‘Foo::operator const int*()’ and ‘Foo::operator Foo::AmbiguousPointerConversion*()’ 
try.cc:25:12: error: type ‘struct Foo’ argument given to ‘delete’, expected pointer 
+1

दोनों रूपांतरण शायद 'const' होना चाहिए, लेकिन बिल्कुल समान होना चाहिए। आप नहीं चाहते कि जानबूझकर अस्पष्टता को 'const' पर अधिभारित करके हल किया जाए। – MSalters

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