2010-07-01 8 views
5

मैं इस प्रकार एक struct एक शीर्षक में परिभाषित किया गया है:वैश्विक स्तर पर या बाहरी रूप से एक संरचना घोषित करते समय मुझे segfaults क्यों मिलता है?

#define LC_ERR_LEN 300 
typedef struct dLC_ERRMSG { 
    short nr; 
    short strategy; 
    char tx[LC_ERR_LEN]; 
} LC_ERRMSG; 

कौन सा मैं जैसे मेरी कोड में उपयोग:

LC_ERRMSG err; 
char *szError; 
szError = strerror(sStatus); 
snprintf(err.tx,LC_ERR_LEN," %s - %s",szFilename,szError); 
/* do something with our error string */ 

काम करता है। हालांकि, मैं वैश्विक स्तर पर LC_ERRMSG err; घोषित करता हूं - यानी फ़ंक्शन के बाहर इसका उपयोग किया जाता है, या यहां तक ​​कि extern LC_ERRMSG err; (जो मेरा मूल इरादा था, क्योंकि मैं केंद्रीय स्थान में त्रुटि स्थिति को पढ़ने में सक्षम होना चाहता हूं), कोड segfaults snprintf कॉल।

क्या आप मुझे कोई संकेत दे सकते हैं क्यों?

ddd मुझे बताता है कि जब वैश्विक स्तर पर घोषित किया जाता है, या कम से कम प्रारंभिक और पठनीय बाहरी घोषित किया जाता है तो स्मृति को सभी शून्यों में प्रारंभ किया जाता है। SzFilename, szError और LC_ERR_LEN मान सभी सही और सार्थक हैं।

+5

यह सी की तरह दिखता है, सी ++ नहीं? –

+1

और परिवर्तनीय नाम एक बिल्ली की तरह दिखते हैं जो कीबोर्ड पर चल रहा था। –

+2

यह एक हंगरी बिल्ली है, क्योंकि मुझे यकीन है कि फ्रीकोज़ीड की बिल्ली भी थी। – maxwellb

उत्तर

3

आपका लिंकर बस प्रतीकों फेंक सकता है, जो उसका मानना ​​है कि उपयोग नहीं किया जाता (जीएनयू लिंकर ऐसा नहीं करता है) । इस मामले में आप उस प्रतीक के साथ ऑब्जेक्ट फ़ाइल को स्पष्ट रूप से लिंक कर सकते हैं।

सी ++ के साथ आप बिना किसी अतिरिक्त प्रयास के अन्य संकलन इकाइयों में परिभाषित वैश्विक वस्तुओं के प्रारंभिकरण के क्रम को नियंत्रित नहीं कर सकते (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 देखें)।

"पहले उपयोग पर निर्माण" मुहावरे का उपयोग करें, जिसका अर्थ केवल एक स्थिर कार्य को फ़ंक्शन के अंदर लपेटना है।

+0

बहुत बहुत धन्यवाद! यह हल हो गया। – relet

2

यदि आपके पास:

// structs.hpp 
#define LC_ERR_LEN 300 
typedef struct dLC_ERRMSG { 
    short nr; 
    short strategy; 
    char tx[LC_ERR_LEN]; 
} LC_ERRMSG; 

और:

// main.cpp 
#include "structs.hpp" 
LC_ERRMSG err; 

int main() 
{ 
    // ... 

    char *szError; 
    szError = strerror(sStatus); 
    snprintf(err.tx, LC_ERR_LEN, "%s - %s", szFilename, szError); 
} 

तो यह काम करना चाहिए। हालांकि, अगर आप main.cpp करने की दूसरी पंक्ति स्विच: तो

extern LC_ERRMSG err; 

आप यह सुनिश्चित करें कि err के लिए भंडारण अपने वस्तु फ़ाइलों में से एक में संकलित किया गया है बनाने की जरूरत है। उदाहरण के लिए, आप इस स्रोत संकलन सकता है:

// globals.cpp 
#include "structs.hpp" 

LC_ERRMSG err; 

और main.o में जिसके परिणामस्वरूप globals.o लिंक।

किसी भी दृष्टिकोण में सेगमेंटेशन गलती नहीं होनी चाहिए। यदि आपको सेगमेंटेशन गलती मिल रही है, तो समस्या यह हो सकती है कि LC_ERR_LEN का एक अलग मान है जब globals.cpp संकलित किया जा रहा है जब main.cpp संकलित किया जा रहा है। या, शायद szFilename या szErrorNULL/खराब हैं। printf परिवार NULL या प्रारूप ध्वज %s के साथ खराब पॉइंटर्स मुद्रित नहीं कर सकता;

#include <stdio.h> 

int main() 
{ 
    printf("%s\n", NULL); 
} 

संपादित करें: मैं इस समस्या का एक और संभावित कारण के बारे में सोचा निम्नलिखित कोड एक विभाजन गलती का कारण बनता है। यदि आप सी संकलक का उपयोग कर रहे हैं तो err एक प्रतीक है जो एक बड़ी परियोजना में कई अलग-अलग वैश्विक चर के नाम के रूप में उपयोग में लाया जा सकता है, तो आप एक प्रतीक संघर्ष कर सकते हैं। यदि आप सी ++ कंपाइलर का उपयोग कर रहे हैं, तो नाम मैंगलिंग प्रक्रिया को यह सुनिश्चित करना चाहिए कि प्रत्येक err का अपना प्रतीक हो। बस सुनिश्चित करें कि आप सी ++ के रूप में संकलित कर रहे हैं।

+0

आपके उत्तर और मैक्सवेल के लिए धन्यवाद। वर्कफ़ॉर्म मैक्सवेलब पोस्ट किया गया है जो मूल रूप से मेरे कोड में था, इससे पहले कि मैंने कहीं और "त्रुटि" घोषित करके समस्या को कम करने की कोशिश की। मैं g ++ के साथ C++ के रूप में संकलित कर रहा हूं। अब तक कोई भाग्य नहीं है। मुझे क्या स्टंप है कि मुझे नहीं पता कि err.tx कैसे दूषित हो सकता है, भले ही इस दौरान इसका उपयोग करने वाला कोई अन्य कोड हो। इसे गतिशील रूप से आवंटित नहीं किया जा रहा है, ताकि मैं इसे गलती से मुक्त कर सकूं। – relet

+0

अपने डीबगर का उपयोग करके, क्या आप सत्यापित करेंगे कि 'szFilename' और 'szError'' snprintf' लाइन पर गैर-'NULL' हैं और' szFilename' ठीक से समाप्त हो गया है? इसके अलावा, पता 'err.tx' क्या है? –

2

+1 डैनियल के उत्तर के लिए +1। यहां एक वर्क्स-फॉर-मी है। आपके लिए काम करता है? डैनियल का जवाब ऊपर उठाओ।


// structs.hpp 
#define LC_ERR_LEN 300 
typedef struct dLC_ERRMSG { 
    short nr; 
    short strategy; 
    char tx[LC_ERR_LEN]; 
} LC_ERRMSG; 

// error.cpp 
#include "structs.hpp" 

LC_ERRMSG err; 

// main.cpp 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include "structs.hpp" 
extern LC_ERRMSG err; 

int main() 
{ 
    // ... 
    char *szFilename = "EXAMPLE.LOG"; 
    int sStatus = 0; 
    char *szError; 
    szError = strerror(sStatus); 
    snprintf(err.tx, LC_ERR_LEN, "%s - %s", szFilename, szError); 

    printf("err.tx: %s", err.tx); 
} 

// Output: 
err.tx: EXAMPLE.LOG - No error 
संबंधित मुद्दे

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