2010-08-15 6 views
6

मैंने कुछ स्थानों को पढ़ा है कि alloca अप्रचलित है और इसका उपयोग नहीं किया जाना चाहिए और इसके बजाय परिवर्तनीय लंबाई Arrays का उपयोग किया जाना चाहिए।क्या एलोका पूरी तरह से बदला जा सकता है?

मेरा प्रश्न यह है: alloca परिवर्तनीय लंबाई सरणी द्वारा पूरी तरह से बदला जा सकता है?

typedef struct { 
    int *value; 
    size_t size; 
    } some_type; 

void SomeExternalFunction(some_type); 

... 

void foo(){ 
    //What I thought to do 
    some_type bar; 
    bar.value=alloca(sizeof(int)*10); 
    SomeExternalFunction(bar); 

    //what should be done without alloca 
    some_type fizz; 
    int tmp[10]; 
    fizz.value=tmp; 
    SoemExternalFunction(fizz); 
} 

मैं कुछ याद आ रही हूँ या इस alloca का एक वास्तविक अच्छा उपयोग है:

मेरी विशेष उदाहरण में मैं कुछ है कि इस तरह दिखता है? इस उदाहरण के लिए भी मान लें कि किसी कारण से मैं स्टैक

+4

यह वास्तव में एक चर-लंबाई सरणी नहीं है ... जैसा कि आपने निरंतर लंबाई निर्दिष्ट की है। और ... यहां तक ​​कि यदि यह * एक परिवर्तनीय लंबाई थी, तो मैं वास्तव में यह नहीं देख रहा हूं कि कोड की मंशा को थोड़ा अधिक अस्पष्ट बनाने के अलावा, आपको यहां क्या खरीदता है। (जाहिर है यदि आप एक कंपाइलर का उपयोग कर रहे हैं जो परिवर्तनीय लंबाई सरणी का समर्थन नहीं करता है, तो आपके पास दोनों के बीच कोई विकल्प नहीं है) – Shog9

+0

यह भी देखें: http://stackoverflow.com/questions/3452434/in-which- मामलों-एएस-एलोका-उपयोगी (शीर्षक पर आधारित एक डुप्लिकेट होगा, लेकिन मुझे लगता है कि आप वास्तव में कुछ और पूछने की कोशिश कर रहे हैं ... हालांकि क्या नहीं बता सकता) – Shog9

उत्तर

13

पर मूल्य आवंटित करना चाहता हूं VLA और alloca के बीच एक महत्वपूर्ण अंतर है: स्मृति आवंटन() रिटर्न वैध मान्य है जब तक कि वर्तमान कार्य जारी रहता है। वीएलए द्वारा कब्जा कर लिया गया स्मृति का जीवनकाल मान्य है जब तक वीएलए का पहचानकर्ता गुंजाइश में रहता है। उदाहरण के लिए आप लूप में alloca() मेमोरी कर सकते हैं और मेमोरी लूप के बाहर उपयोग कर सकते हैं, एक वीएलए चलेगा क्योंकि लूप समाप्त होने पर पहचानकर्ता गुंजाइश से बाहर हो जाता है। इसका मतलब यह है, तो आप alloca() और पर्याप्त ढेर अंतरिक्ष के साथ ऐसा कर सकते हैं:

typedef struct node { int data; struct node *next; }; 
void fun() 
{ 
struct node *n=0; 
int d; 
/* Now we are building a single-linked list on the stack! */ 
while(d=get_something()) { 
    struct node *x=alloca(sizeof(*x)); 
    x->next=n; 
    x->data=d; 
    n=x; 
} 
do_something_with(n); 
} // and the whole thing is deleted here.. 

आप Vlas के साथ ऐसा नहीं कर सकते।

+0

FWIW: यह दोनों का एक बड़ा जवाब होगा [किस मामले में alloca() उपयोगी है?] (Http://stackoverflow.com/questions/3452434/in-which-cases-is-alloca-useful) और [alloca (n) और char x के बीच क्या अंतर है \ [n \]?] (http://stackoverflow.com/questions/2614561/whats-the-difference-between-allocan-and-char-xn) – Shog9

+0

यह अंतर के बारे में एक अच्छा जवाब है, लेकिन आप यह भी चाह सकते हैं यह ध्यान रखें कि 'एलोका' का व्यवहार अनिवार्य रूप से कार्यान्वयन-परिभाषित है क्योंकि यह किसी भी (वर्तमान) मानक में निर्दिष्ट नहीं है। –

+0

वैसे, ** ** वीएलए के साथ ऐसा करने का एक तरीका है: फ़ंक्शन को रिकर्सिव बनाएं और गहरे स्तर पर 'do_something_with (n) 'को कॉल करें। :-) दरअसल, इसके लिए मेरे पास वास्तविक दुनिया का उपयोग था, जिसे मैंने अभी तक लागू नहीं किया है: '/ lib/ld.so' का हल्का कार्यान्वयन जो स्टैक पर गतिशील लिंकिंग करता है ताकि छोटे में 'malloc' ओवरहेड लाने से बचें प्रोग्राम जो इसका उपयोग नहीं करते हैं। अंत में, यह सभी गतिशील लिंकिंग डेटा को अनदेखा और त्याग देगा यदि केवल और 'libdl' लिंक नहीं किया गया है; अन्यथा यह रिक्त स्थान के गहरे स्तर से '_start' को कॉल करेगा। –

1

allocamalloc और free द्वारा पूरी तरह से बदला जा सकता है। यह थोड़ा और काम है लेकिन जब तक कि आप बहुत सावधान नहीं हैं, यह आवश्यक है। alloca या सी 99 vla का उपयोग कर लगभग सभी कोड अतिप्रवाह हमलों को ढेर करने के लिए कमजोर है, और कई कार्यान्वयन में, वे विशेषाधिकार उन्नति का कारण बन सकते हैं। यह पता लगाने के लिए कोई पोर्टेबल तरीका नहीं है कि ढेर कितना बड़ा है या कितनी स्टैक स्पेस छोड़ी गई है (या संकलक के आंतरिक उपयोग या आगे फ़ंक्शन कॉल के लिए अनुरोध किए गए आकार से अधिक ओवरहेड की आवश्यकता हो सकती है), तो एकमात्र उचित चीज़ जो आप कर सकते हैं vla's/alloca सुरक्षित करें आपके द्वारा समर्थित डेटा के आकार पर बहुत ही कम कृत्रिम सीमा लगाएं (उदाहरण के लिए कुछ केबी)। इस बिंदु पर आप सादे गैर-परिवर्तनीय-लंबाई स्वचालित वस्तुओं का उपयोग कर सकते हैं ...

+0

ढेर पूरी तरह से ढेर की जगह है। नहीं। –