2010-07-24 7 views
6

साथ मैं निम्नलिखित कोड है:सी ++ पूर्णांक एक [n] जी में ++ काम कर रहा है, लेकिन नहीं VS2008

... 
int n; 
cin >> n; 
int numbers[n]; 
... 

यह पर जी का उपयोग कर मैक NetBeans के साथ संकलित ++ (मुझे लगता है कि) और उस पर VS2008 का उपयोग कर संकलन नहीं किया विंडोज। यह हर कंपाइलर के साथ काम करना इतना मुश्किल क्यों है? सरणी का आकार इसे आवंटित करने से पहले जाना जाता है।

संपादित करें: मुझे std::vector पता है। असल में यह होमवर्क असाइनमेंट का हिस्सा था और मैंने इसे मैक पर काम पर शुरू किया, फिर घर आया और आश्चर्यचकित हुआ कि यह वीएस -2008 पर काम नहीं करता था। सारे सवालों के जवाब देने के लिए धन्यवाद। लेकिन मुझे अभी भी यह तार्किक लगता है कि यदि संकलक alloc(123) जैसे कुछ कोड उत्पन्न कर सकता है, जहां मान 123 हार्डकोड किया गया है, तो यह alloc(n) जैसे कुछ उत्पन्न क्यों नहीं कर सकता है, जहां आपको int n या कुछ मेमोरी पते से n मिलता है। डिफ़ॉल्ट रूप से ऐसा कुछ करने की अनुमति देने के लिए यह और अधिक तार्किक लगता है।

+4

उस –

+1

@RC के लिए कुछ सीपीपी असली सामग्री जैसे 'std :: vector ' का उपयोग क्यों न करें: यह एक अच्छा जवाब है - इसे वास्तविक बनाएं! –

+1

@ ड्रू: किया गया;) धन्यवाद –

उत्तर

16

हालांकि सरणी का आकार आवंटित होने से पहले ज्ञात है, फिर भी यह रनटाइम तक ज्ञात नहीं है। इसे परिवर्तनीय लंबाई सरणी (VLA) के रूप में जाना जाता है और यह एक C99ism है, जिसे डिफ़ॉल्ट रूप से सक्षम एक्सटेंशन द्वारा g ++ में समर्थित किया जाता है। स्पष्ट होने के लिए, यह अनुरूप नहीं है C++ 98/03, और इस प्रकार विज़ुअल सी ++ इसे अस्वीकार करने के अपने अधिकार में अच्छी तरह से है।

यदि आप वास्तव में रनटाइम गतिशील आकार चाहते हैं, तो ढेर पर आवंटित करें (नए [] के माध्यम से)। यह हर जगह काम करेगा, और एक बोनस के रूप में, आपको ढेर ओवरफ्लो से बचाएगा। Vlas के लिए

+7

असल में, 'नया [] 'का उपयोग न करें। 'Std :: vector' का प्रयोग करें। – GManNickG

+0

@ जीएमएन - मैं पूरी तरह से सहमत हूं! मेरे जल्दबाजी में मैंने उस विकल्प का उल्लेख करने की उपेक्षा की, लेकिन इस बिंदु पर आरसी के जवाब को चेरीपिक नहीं करना चाहते! :) –

+0

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

12

क्योंकि सरणी का आकार मानक सी ++ में एक संकलन समय स्थिर होना चाहिए (8.3.4 §1 देखें)।

1

समर्थन 2008

+7

या सी ++ में बिल्कुल। – GManNickG

2

कुछ इसी तरह के लिए std::vector<int> जैसे कुछ सीपीपी असली सामान का उपयोग नहीं के साथ किया ne कर सकते हैं

int* numbers = (int*)alloca(n * sizeof(int)); // equivalent to int numbers[n] 

यह नहीं है दृश्य स्टूडियो में मौजूद नहीं है अनुशंसित कार्य, लेकिन अगर सावधानीपूर्वक उपयोग किया जाता है, तो वही परिणाम देता है।

+4

और ध्यान से तैयार किए गए इनपुट के साथ, उपयोगकर्ता स्टैक को ओवरफ़्लो कर सकता है और बुरे लोगों के लिए स्कोर कर सकता है। –

+0

@ फ्रांसी, क्या आपके पास इस विशेष कार्यक्रम के लिए "ध्यान से तैयार किए गए इनपुट" को डिजाइन करने के अलावा कुछ भी बेहतर नहीं है? :) बेहतर प्रयास करें http://www.crackmes.de – ruslik

+0

वीएलए और एलोका() के बीच एक महत्वपूर्ण अंतर है। वीएलए घोषणा के अपने दायरे में बनी हुई है, जबकि alloca() ब्लॉक * समारोह * के दायरे के लिए बनी हुई है। एक पाश शरीर में एक वीएलए घोषित करने से शरीर में एक एलोका करने के रूप में कम ढेर का उपयोग होता है। तो यदि आप लूप में आवश्यक सरणी आकार के बारे में जानेंगे, तो एलोका आपके लिए काम नहीं कर सकता है। –

2

सरणी आयाम बुक करके निरंतर अभिव्यक्ति होना चाहिए जिसका मूल्य एक से अधिक या बराबर है। अर्थ अभिन्न शाब्दिक स्थिरांक, एन्यूमेरेटर्स या अभिन्न प्रकार की कॉन्स ऑब्जेक्ट्स में निरंतर अभिव्यक्ति जो स्वयं को कॉन्स्ट एक्सप्रेशन से प्रारंभ की जाती हैं। एक गैर स्थिरांक जिसका मान रनटाइम तक ज्ञात नहीं है, किसी सरणी के आयाम को निर्दिष्ट करने के लिए उपयोग नहीं किया जा सकता है।

लेकिन मैं जिस कंपाइलर संस्करण का उपयोग करता हूं, वह आपके द्वारा वर्णित तरीके की अनुमति देता है।

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