2010-12-28 13 views
11

मुझे अपने प्रोग्राम में सेगमेंटेशन गलती त्रुटि का कारण समझ में नहीं आता है। कोड उपलब्ध है hereपरिवर्तनीय कारणों सेगमेंटेशन गलती की घोषणा

लाइन 2 पर मैं PclImage वैरिएबल घोषित करता हूं, जिसे स्ट्रिप की सरणी की तरह टाइपपीफ के साथ परिभाषित किया गया है। PclImage प्रकार की परिभाषा निम्नलिखित (src से/libMyKinect.h फ़ाइल) है:

typedef struct { 
    int valid; 
    float x; 
    float y; 
    float z; 
    unsigned char blue; 
    unsigned char green; 
    unsigned char red; 
} Point3d; 

typedef Point3d PclImage[480][640]; 

कार्यक्रम अच्छी तरह से काम करता है, लेकिन जब मैं एक दूसरे PclImage घोषित, मैं मैं के रूप में के रूप में जल्द ही एक विभाजन गलती मिल कार्यक्रम का शुभारंभ।

उदाहरण के लिए, यदि पहली फ़ाइल के लाइन 30 पर मैं PclImage bgPcl; जोड़ता हूं तो प्रोग्राम तुरंत क्रैश हो जाता है।

क्या कोई मेरी मदद कर सकता है?

उत्तर

14

यदि आप स्थानीय चर (स्टैक पर) के रूप में PclImage घोषित करते हैं, तो आपको स्टैक ओवरफ़्लो के कारण सेगमेंटेशन गलती मिल सकती है।

PclImage 307,200 तत्वों वाला एक सरणी है, जिनमें से प्रत्येक आकार में लगभग 20 बाइट्स है (इसलिए) पूरी सरणी आकार में लगभग 6 एमबी है। यह बेहद असंभव है कि ढेर उन दो सरणी रखने के लिए काफी बड़ा है; यह एक भी शामिल करने के लिए पर्याप्त नहीं हो सकता है (एक बहुत सामान्य नियम के रूप में, यह आमतौर पर अधिकांश डेस्कटॉप ओएस पर सुरक्षित है यह मानने के लिए कि आपके पास कम से कम 1 एमबी स्टैक स्पेस उपलब्ध है)।

जब आपके पास ऐसी बड़ी वस्तुएं होती हैं, तो आपको उन्हें गतिशील रूप से आवंटित करना चाहिए (malloc और दोस्तों का उपयोग करके) या, यदि आप पुनर्वित्त से संबंधित नहीं हैं, तो सांख्यिकीय रूप से।

1

मैं जेम्स से सहमत हूं कि ढेर पर उन बड़े सरणी आवंटित करने का सबसे अधिक कारण है। हालांकि, प्रत्येक PclImage प्रत्येक के बारे में केवल 6 मेग तक जोड़ता है। जब तक आप एक सीमित स्मृति वातावरण में परिचालन नहीं कर रहे हैं, यह करने योग्य होना चाहिए। मैंने पहले ढेर पर बहुत बड़े सरणी आवंटित की हैं। एम्बेडेड सिस्टम पर भी।

malloc का उपयोग करने के जेम्स के सुझाव शायद इसे ठीक करेंगे (इस मुद्दे को सत्यापित करने के लिए प्रयास करें)। हालांकि, जब संभव हो तो गतिशील आवंटन से बचने के लिए मुझे एक अच्छी नीति मिलती है। मॉलोक के संभावित विकल्प बाह्य संदर्भ में सरणी घोषित करना होगा, या अपने धागे के ढेर के आकार को बढ़ाने के लिए होगा। उपयोगकर्ता द्वारा बनाई गई प्रक्रियाओं और/या धागे में अक्सर डिफ़ॉल्ट रूप से आवंटित काफी छोटे स्टैक होते हैं। यह निर्धारित करने के लिए एक साधारण मामला हो सकता है कि यह कहां सेट है और इसे अपनी आवश्यकताओं के लिए काफी बड़ा ढेर दें।

उदाहरण के लिए, यदि यह Windows CreateThread() दिनचर्या के साथ बनाए गए थ्रेड से चलाया जाता है, तो दूसरा पैरामीटर स्टैक आकार को नियंत्रित करता है। यदि आप इसे 0 (अधिकांश लोगों के रूप में करते हैं) के साथ डिफ़ॉल्ट करते हैं, तो यह डिफ़ॉल्ट स्टैक आकार लेता है। जैसा कि मैं कह सकता हूं, यह "केवल" 1 एमबी है।

+0

आप एम्बेडेड सिस्टम में स्मृति का अनुमान लगाने के लिए काफी हद तक। 32k से अधिक RAM होने के कारण विशाल है। । । और मैं 2017 के परिप्रेक्ष्य से ले रहा हूं। 2010 में, महसूस करें कि 16K उन हिस्सों में उपलब्धता थी जहां हमने रैम के लिए विभाजन किया था। – iheanyi

+0

@hiheanyi - टिप्पणियों में कहा गया है, कुछ डिवाइस मेमोरी-सीमित हैं, लेकिन मैं यहां अनुभव से बात कर रहा था, अनुमान नहीं। बेशक ymmv, लेकिन इसका मतलब यह नहीं है कि प्रत्येक एम्बेडेड डेवलपर आपके द्वारा काम किए जाने वाले सिस्टम पर काम कर रहा है। –

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