C ++ में स्टेटिक ऐरे बनाम डायनेमिक ऐरे


91

C ++ में एक स्थिर सरणी और एक गतिशील सरणी के बीच अंतर क्या है?

मुझे अपनी कक्षा के लिए एक असाइनमेंट करना है और यह कहता है कि स्थिर सरणियों का उपयोग न करें, केवल डायनेमिक एरेज़। मैंने पुस्तक और ऑनलाइन में देखा है, लेकिन मुझे समझ में नहीं आ रहा है।

मुझे लगा कि स्थिर समय पर स्थैतिक का निर्माण किया गया था और रनटाइम के दौरान गतिशील, लेकिन मैं इसे स्मृति आवंटन के साथ गलत कर सकता हूं।

क्या आप C ++ में स्थिर सरणी और डायनामिक सरणी के बीच अंतर बता सकते हैं?


1
स्थैतिक गतिशील के विपरीत नहीं है। या तो आप जिस पुस्तक का उपयोग कर रहे हैं वह भयानक है, या आप इसे संदर्भ से बाहर ले जा रहे हैं। मैं नीचे एक नया उत्तर जोड़ने जा रहा हूँ उम्मीद है कि यह स्पष्ट करने के लिए।
यहोशू क्लेटन

3
इस प्रश्न में आरेख देखें: stackoverflow.com/a/11698458/1143274 स्टैटिक सरणियों को स्टैक या ढेर पर आवंटित नहीं किया गया है।
एवगेनी सर्गेव

* फिक्स्ड ऐरे बनाम डायनेमिक ऐरे
csguy

जवाबों:


102

स्थानीय सरणियों को स्टैक पर बनाया जाता है, और स्वचालित भंडारण अवधि होती है - आपको मेमोरी को मैन्युअल रूप से प्रबंधित करने की आवश्यकता नहीं होती है, लेकिन जब वे कार्य समाप्त होते हैं तो वे नष्ट हो जाते हैं। वे जरूरी एक निश्चित आकार है:

int foo[10];

Arrays के operator new[]पास गतिशील भंडारण अवधि होती है और इसे ढेर पर संग्रहीत किया जाता है (तकनीकी रूप से "फ्री स्टोर")। उनके पास कोई भी आकार हो सकता है, लेकिन आपको उन्हें आवंटित करने और उन्हें मुक्त करने की आवश्यकता है क्योंकि वे स्टैक फ्रेम का हिस्सा नहीं हैं:

int* foo = new int[10];
delete[] foo;

18
यह सही है, लेकिन केवल यह वर्णन करने के लिए कि यह कैसे काम करता है। कृपया वास्तविक कोड में ऐसा न करें लेकिन इसके बजाय एक std :: वेक्टर का उपयोग करें।
एडी प्रोक

23
@ ईडी: यह इस स्थिति पर निर्भर करता है कि क्या एक वेक्टर आवश्यक है
केसबश

6
@ कैशेबश: आप किस स्थिति में एक सरणी पसंद करेंगे? "आपको हमेशा सरणियों के बजाय वैक्टर या देवताओं का उपयोग करना पसंद करना चाहिए।" - हर्ब सटर (अधिक असाधारण सी ++)
एडी प्रैंक

16
@EddyPronk स्मृति फ़्रेग्मेंटेशन कारणों से कोई एक निश्चित सरणी का उपयोग पूल के प्रकार के रूप में कर सकता है। हर मामला ढेर की मांग नहीं करता है, स्टैक आधारित सरणियों का उपयोग करने के लिए विशेष लाभ हैं। आप एसटीडी का इलाज कर रहे हैं :: वेक्टर एक सुनहरा हथौड़ा, एक सामान्य विरोधी पैटर्न।
void.pointer

4
@ ईडिप्रोनक: मुझे पूरा यकीन है कि हर्ब सटर का मतलब डायनेमिक एरेज़ होता है, जैसे int* foo = new int[N]कि आपको deleteखुद से और इसलिए अपवाद की उपस्थिति में सावधान रहना चाहिए। स्थैतिक सरणियों में ये समस्याएं नहीं हैं।
अलेक्जेंडर मालाखोव

31

स्थैतिक C और C ++ में एक कीवर्ड है, इसलिए सामान्य वर्णनात्मक शब्द के बजाय, वैरिएबल या सरणी पर लागू होने पर स्थैतिक का बहुत विशिष्ट अर्थ होता है। भ्रम को कम करने के लिए, अलग संदर्भों के भीतर इसके तीन अलग-अलग अर्थ हैं। इस वजह से, एक स्थिर सरणी या तो स्थिर या गतिशील हो सकती है।

मुझे समझाने दो:

पहला C ++ विशिष्ट है:

  • एक स्थिर वर्ग का सदस्य एक ऐसा मूल्य है जो कंस्ट्रक्टर के साथ तात्कालिक नहीं है या विध्वंसक के साथ हटा दिया जाता है। इसका मतलब यह है कि सदस्य को इनिशियलाइज़ करना होगा और कुछ अन्य तरीके से बनाए रखना होगा। स्थैतिक सदस्य बिंदुओं को अशक्त करने के लिए प्रारंभ किया जा सकता है और फिर पहली बार एक निर्माणकर्ता को बुलाया जाता है। (हाँ, यह स्थिर और गतिशील होगा)

दो सी से विरासत में मिले हैं:

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

  • फ़ंक्शनल वैरिएबल फ़ंक्शंस के बाहर घोषित वैश्विक वैरिएबल हैं जो केवल एक ही मॉड्यूल (किसी अन्य # शामिल स्रोत के साथ स्रोत कोड फ़ाइल) के भीतर से एक्सेस किए जा सकते हैं

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


4
+1, आपका उत्तर सबसे सटीक और सटीक है और उसे अधिक वोट प्राप्त होने चाहिए।
जेड बोसोन

यदि आप new[]ऑपरेटर के साथ सरणी का आकार घोषित करते हैं , तो यह कैसे होता है कि आकार रनटाइम तक ज्ञात नहीं है? यानीint* p = new int[10]
wulfgarpro

"उन्हें मुख्य फ़ंक्शन चलने से पहले आवंटित किया गया है।" प्रासंगिक ब्लॉक में प्रवेश करने से पहले स्टैक चर को क्यों आवंटित करें?
हमेशा

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

@JoshuaClayton मुझे लगता है कि यह सही नहीं हो सकता। जब आप यह नहीं जानते कि कितनी बार इसमें प्रवेश किया जाएगा तो आप एक पुनरावर्ती कार्य के लिए स्टैक फ्रेम (नोटिस बहुवचन) को कैसे आवंटित कर सकते हैं?
हमेशा

11

मुझे लगता है कि आपकी कक्षा में इस्तेमाल किए जा रहे शब्दार्थ भ्रमित हैं। शायद 'स्टैटिक' से जो मतलब है, वह केवल "स्थिर आकार" है, और "डायनामिक" का जो अर्थ है वह "परिवर्तनशील आकार" है। उस स्थिति में, एक स्थिर आकार सरणी इस तरह दिख सकती है:

int x[10];

और "गतिशील" एक बस किसी भी प्रकार की संरचना होगी जो अंतर्निहित भंडारण को बढ़ाने या रनटाइम में कमी करने की अनुमति देती है। अधिकांश समय, std::vectorC ++ मानक पुस्तकालय से वर्ग पर्याप्त होगा। इसे इस तरह उपयोग करें:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vector है operator[] तो आप एक सरणी के रूप में ही अर्थ विज्ञान के साथ उपयोग कर सकते हैं, को परिभाषित किया।


1
मुझे लगता है कि यह स्पष्ट रूप से स्पष्ट है कि "डायनेमिक एरे" से उनका तात्पर्य डायनामिक रूप से आवंटित एरे से है (अर्थात, वह एक जिसमें आकार डायनामिक रूप से, रनटाइम पर निर्दिष्ट किया जा सकता है)। जैसेnew int[10]
jalf

@ जैलफ: मैं 'स्थिर' शब्द के बारे में अधिक चिंतित था। मैं एक "डायनेमिक एरे" को संगति के लिए एक आबंटित या परिवर्तनशील आकार की ऐरे कहना पसंद करता हूं।
बेन कोलिन्स

अच्छी बात यह है कि एक स्टैटिक ऐरे को स्वचालित किया जा सकता है और स्टैक पर लागू किया जा सकता है या वैश्विक हो सकता है और डेटा सेक्शन में लागू किया जा सकता है। दोनों स्थिर हैं लेकिन आंतरिक रूप से कोड जो उन्हें एक्सेस करता है वह बहुत अलग हो सकता है।
जेड बोसोन

9

स्थिर सरणियों को संकलन समय पर मेमोरी आवंटित की जाती है और मेमोरी को स्टैक पर आवंटित किया जाता है। जबकि, गतिशील सरणियों को रनटाइम पर मेमोरी आवंटित की जाती है और मेमोरी को हीप से आवंटित किया जाता है।

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.

4
एक वैश्विक सरणी एक स्थिर सरणी है और इसे डेटा अनुभाग में लागू किया जाता है और स्टैक से नहीं।
Z बोसॉन

8

किन शब्दों का क्या अर्थ है, इसकी स्पष्ट परिभाषा रखना महत्वपूर्ण है। दुर्भाग्य से स्थैतिक और गतिशील सरणियों के कई अर्थ हैं।

स्टेटिक वैरिएबल वैरिएबल मेमोरी एलोकेशन के उपयोग से परिभाषित चर होते हैं । यह C / C ++ से स्वतंत्र एक सामान्य अवधारणा है। C / C ++ में हम वैश्विक, फ़ाइल या स्थानीय स्कोप जैसे स्थैतिक चर बना सकते हैं:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

स्वचालित चर आमतौर पर स्टैक-आधारित मेमोरी आवंटन का उपयोग करके कार्यान्वित किए जाते हैं । इस तरह से C / C ++ में एक स्वचालित सरणी बनाई जा सकती है:

foo() {
    int w[10]; //automatic array

क्या इन सरणियों x, y, z, औरw आम में क्या है कि उनमें से प्रत्येक के लिए आकार तय हो गया है और संकलन समय पर परिभाषित किया गया है।

कारणों में से एक यह है कि एक स्वचालित सरणी और एक स्थिर सरणी के बीच के अंतर को समझना महत्वपूर्ण है, स्थिर भंडारण आमतौर पर ऑब्जेक्ट फ़ाइल के डेटा अनुभाग (या BSS अनुभाग ) में लागू किया जाता है और कंपाइलर सरणियों तक पहुंचने के लिए निरपेक्ष पते का उपयोग कर सकता है। जो स्टैक-आधारित भंडारण के साथ असंभव है।

डायनेमिक ऐरे से आमतौर पर जो मतलब होता है वह एक ऐसा नहीं है जो रेज़िजेबल है, लेकिन एक रन-टाइम पर निर्धारित निश्चित आकार के साथ डायनेमिक मेमोरी एलोकेशन का उपयोग करके लागू किया गया है। C ++ में यह newऑपरेटर का उपयोग करके किया जाता है ।

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

लेकिन रनटाइम का उपयोग करके परिभाषित फ़िक्सेस आकार के साथ एक स्वचालित सरणी बनाना संभव है alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))

एक सच्चे डायनेमिक ऐरे के लिए std::vectorC ++ (या C में वैरिएबल लेंथ एरे ) जैसी किसी चीज का उपयोग करना चाहिए ।

ओपी के प्रश्न में असाइनमेंट के लिए क्या मतलब था? मुझे लगता है कि यह स्पष्ट है कि जो चाहता था वह एक स्थिर या स्वचालित सरणी नहीं था, लेकिन एक है जो या तो गतिशील मेमोरी आवंटन का उपयोग करता थाnew ऑपरेटर या गैर-निश्चित आकार के सरणी का उपयोग करके उपयोग करता था जैसे std::vector


3

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


2

आपके पास एक छद्म गतिशील सरणी हो सकती है जहां आकार उपयोगकर्ता द्वारा रनटाइम पर सेट किया जाता है, लेकिन फिर उसके बाद तय किया जाता है।

int size;
cin >> size;
int dynamicArray[size];

मानक C ++ का हिस्सा नहीं है (C99 में और gcc के लिए संकलक विस्तार के रूप में)।
दुर्घटना

1

स्थैतिक सरणी :

  1. स्टैटिक सरणियों को संकलन समय पर मेमोरी आवंटित की जाती है।
  2. आकार तय है।
  3. स्टैक मेमोरी स्पेस में स्थित है।
  4. उदाहरण के लिए। : इंट सरणी [10]; // आकार 10 की सरणी

गतिशील सरणी:

  1. मेमोरी को रन टाइम पर आवंटित किया जाता है।
  2. आकार निश्चित नहीं है।
  3. हीप मेमोरी स्पेस में स्थित है।
  4. उदाहरण के लिए। : int * array = नया int [10];

0

हाँ सही स्थैतिक सरणी संकलन समय पर बनाया गया है जहाँ गतिशील सरणी रन समय पर बनाई गई है। जहां तक ​​उनके स्मृति स्थानों के साथ अंतर का संबंध है, स्थैतिक स्टैक पर स्थित हैं और ढेर पर गतिशील बनाए जाते हैं। जो कुछ भी ढेर पर स्थित होता है, उसे तब तक मेमोरी प्रबंधन की आवश्यकता होती है जब तक कि कचरा संग्रहकर्ता के रूप में .net फ्रेमवर्क के मामले में मौजूद न हो अन्यथा मेमोरी लीक होने का खतरा होता है।


0

स्थैतिक सरणी: दक्षता। किसी भी गतिशील आवंटन या सौदे की आवश्यकता नहीं है।

स्थिर संशोधक सहित फ़ंक्शन में C, C ++ में घोषित ऐरे हैं। उदाहरण: स्थिर int foo [5];


1
@admdrew, यह सच है लेकिन इस सवाल का जवाब कभी नहीं दिया गया। सबसे अच्छा जवाब यहोशू क्लेटन का जवाब है, लेकिन मुझे लगता है कि एक बेहतर जवाब यह एक है stackoverflow.com/questions/17775066/…
Z boson

@Zboson पता करने के लिए अच्छा है, धन्यवाद। हेह और मुझे एहसास हुआ कि मैंने वह टिप्पणी लगभग एक साल पहले की थी।
प्रशंसा की

-3

ऐरे के साइड में तत्वों पर देने के साथ स्टैटिक अर्करी मीन्स

सरणी में साइड पर तत्वों को दिए बिना डायनेमिक अर्करी मीन्स

उदाहरण:

     char a[10]; //static array
       char a[];  //dynamic array

मुझे लगता है कि उन्होंने सही कहा। जब आप सरणी के लिए एक सटीक लंबाई रखते हैं तो यह एक स्थिर सरणी है और जब आप लंबाई नहीं देते हैं तो यह एक गतिशील सरणी होती है। लेकिन जैसा कि वह अंग्रेजी लिखना नहीं जानता है, इसलिए लोग इस उत्तर को चिह्नित कर रहे हैं।
मुहम्मद तेय्यब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.