मान लीजिए मैं कुछ पुनरावर्ती क्रिया है कि एक ग्राफ संरचना manipulates है:मैं सी में गहराई से रिकर्सिव फ़ंक्शन के स्टैक फ्रेम को कैसे कम कर सकता हूं?
typedef struct Node {
Data data;
size_t visited;
size_t num_neighbors;
struct Node *neighbors[];
} Node;
void doSomethingWithNode(Node *node)
{
if ((!node) || node->visited)
return;
node->visited = 1;
/* Do something with node->data */
size_t /* some local variables */;
size_t i;
for (i = 0; i < node->num_neighbors; i++)
{
/* Do some calculations with the local variables */
if (/* something */)
doSomethingWithNode(node->neighbors[i]);
}
}
क्योंकि स्थानीय चर मैं पाश में उपयोग किए जाने वाले
, संकलक (gcc
) एक बड़े से भी मैं-होगा की तरह ढेर फ्रेम बनाता है इस फ़ंक्शन के लिए (pushq
और popq
की अच्छी संख्या -O3
के साथ भी निर्देश), जो एक समस्या है, क्योंकि यह गहराई से रिकर्सिव है। चूंकि इससे कोई फर्क नहीं पड़ता कि मैं किस क्रम में नोड्स पर जाता हूं, मैं Node
पॉइंटर्स के ढेर का उपयोग करने के लिए इस कोड को दोबारा कर सकता हूं, इस प्रकार प्रतिरक्षा प्रति एक सूचक को ओवरहेड को कम करता है।
- क्या कोई संकेत है कि मैं इस समस्या को हल करने के लिए संकलक (
gcc
) दे सकता हूं? - यदि नहीं, तो क्या असेंबली का उपयोग किए बिना पॉइंटर्स के मेरे ढेर के लिए कॉल स्टैक का उपयोग करना संभव है?
सभी पुनरावर्ती कोड भी उपयोग कर के रूप में गैर पुनरावर्ती व्यक्त किया जा सकता लूप। लिंक करते समय आप स्टैक आकार को भी बढ़ा सकते हैं (उदाहरण के लिए '-z स्टैक-साइज' [लिंकर विकल्प] (https://sourceware.org/binutils/docs/ld/Options.html#Options) का उपयोग करके) डिफ़ॉल्ट 8 एमबी (लिनक्स पर) पर्याप्त नहीं है। हालांकि मुझे वास्तव में आवश्यकता दिखाई नहीं दे रही है क्योंकि स्थानीय चर की संख्या सापेक्ष छोटी है (पाठ्यक्रम के "कुछ स्थानीय चर" के आधार पर) और बिना सरणी के। और स्थानीय चर को वास्तव में 'पुश' और' पॉप 'निर्देशों से नहीं संभाला जाता है, तो क्या आप वास्तव में सही कोड देख रहे हैं? –
जीसीसी मैनुअल पेज में एक संक्षिप्त रूप के बाद मुझे एक विकल्प -फंससर्व-स्टैक दिखाई देता है। या तुमने कोशिश की? – Marian
@Marian: धन्यवाद! मैं इसे आजमाऊंगा। – Matt