libdispatch
, queue.h
के लिए ऐप्पल की शीर्षलेख फ़ाइलों में से एक में, निम्न चेतावनी प्रकट होती है:सी डब्ल्यू/ब्लॉक: ढेर से बाहर निकलने वाले स्टैक-आधारित ब्लॉक
// The declaration of a block allocates storage on the stack.
// Therefore, this is an invalid construct:
dispatch_block_t block;
if (x) {
block = ^{ printf("true\n"); };
} else {
block = ^{ printf("false\n"); };
}
block(); // unsafe!!!
// What is happening behind the scenes:
if (x) {
struct Block __tmp_1 = ...; // setup details
block = &__tmp_1;
} else {
struct Block __tmp_2 = ...; // setup details
block = &__tmp_2;
}
// As the example demonstrates, the address of a stack variable is
// escaping the scope in which it is allocated. That is a classic C bug.
जितना मैं कर सकता हूं, मैं इस परीक्षण की अनुमति नहीं दे सकता जो इस बग का उदाहरण देता है। मैं ब्लॉक बना सकता हूं जो ढेर पर तत्काल होते हैं, लेकिन वे (प्रतीत होते हैं) हमेशा एक दूसरे के संबंध में दायरे से बाहर होने पर, स्टैक पर अद्वितीय पते पर दिखाई देते हैं।
मुझे कल्पना है कि इसका उत्तर सरल है, लेकिन यह मुझसे बच निकला है। क्या कोई मेरी (सीमित) समझ में अंतर को भर सकता है?
संपादित करें: मैंने this प्रतिक्रिया देखी है, लेकिन मुझे समझ में नहीं आता कि यह उदाहरण ऊपर दिए गए मेरे उदाहरण में अनुवाद कैसे कर सकता है। क्या कोई मुझे if
संरचनाओं का उपयोग करके एक उदाहरण दिखा सकता है?
आपके द्वारा पोस्ट किए गए लिंक को एक अलग समस्या के साथ करना है, अर्थात्, बंद होने से परिवर्तनीय चर की उपस्थिति में अजीब कार्य करना प्रतीत होता है। प्रश्न देखें ["जावास्क्रिप्ट: लूप बंद करें?"] (Http://stackoverflow.com/questions/5555464/javascript-closure-of-loop), जो जावास्क्रिप्ट में एक ही समस्या है। हालांकि, ऐसा लगता है कि उन्होंने इस टिप्पणी के खिलाफ गलती की चेतावनी दी है। क्या ब्लॉक इन दिनों स्वचालित रूप से प्रतिलिपि बनाते हैं? मैं भी जानना चाहता हूं। –
मैंने थोड़ा सा प्रयास किया है लेकिन हमेशा आपके जैसा ही परिणाम मिलता है, ब्लॉक स्ट्रक्चर फ़ंक्शन स्कोप पर प्रतीत होते हैं। शायद बहुत से लोगों को काटा गया और उन्होंने इसे बदल दिया? –