2014-10-01 11 views
5

मुझे प्रारंभिक-सूची में QString का उपयोग करते समय एक्सेस-उल्लंघन का सामना करना पड़ा जो मुझे समझ में नहीं आया।प्रारंभकर्ता सूची में QString पहुंच उल्लंघन का कारण बनता है। क्या गलत है?

यहां एक न्यूनतम उदाहरण है जो समस्या को पुन: उत्पन्न करता है।

// file ClassA.h 
#pragma once 
#include <QString> 

struct Parameter 
{ 
    QString stringPar; 
}; 

class ClassA 
{ 
    QString m_string1; 

public: 
    void function(Parameter pars); 
}; 

ClassA के कार्यान्वयन ...

// file ClassA.cpp 
#include "ClassA.h" 

void ClassA::function(Parameter pars) 
{ 
    m_string1 = pars.stringPar; // last line called in my code when the crash happens 
} 

और main.cpp

// file main.cpp 
#include "ClassA.h" 

int main() 
{ 
    ClassA classA; 

    classA.function({ QString("jkjsdghdkjhgdjufgskhdbfgskzh") }); 

    // when using this code the problem does not occur 
    //Parameter par = { QString("jkjsdghdkjhgdjufgskhdbfgskzh") }; 
    //classA.function(par); 

    return 0; 
} 

उल्लंघन के समय में कॉल स्टैक:

Qt5Cored.dll!QGenericAtomicOps<QAtomicOpsBySize<4> >::load<long>(const long & _q_value) Line 96 
Qt5Cored.dll!QBasicAtomicInteger<int>::load() Line 142 
Qt5Cored.dll!QtPrivate::RefCount::ref() Line 57 
Qt5Cored.dll!QString::operator=(const QString & other) Line 1355 
EducationalCode.exe!ClassA::function(Parameter pars) Line 6 
EducationalCode.exe!main() Line 8 

कुछ लगता है कॉपी असाइनमेंट के साथ गलत होने के लिए i एन कक्षाए :: समारोह() लेकिन मुझे यकीन नहीं है कि यह क्या है। जब मैं

function(const Parameter& pars); 

को समारोह के हस्ताक्षर बदल यह या तो दुर्घटना नहीं है।

क्या आपके पास कोई विचार है?

+2

ऐसा लगता है कि यह क्रैश होना चाहिए ... और यह मुझ पर क्रैश नहीं हुआ (Qt5.3, gcc4.8.2, कुबंटू 32-बिट)। क्यूटी, ओएस, आदि का क्या कंपाइलर संस्करण? – HostileFork

+0

विंडोज 7 64 बिट, विजुअल स्टूडियो 2013 अपडेट 2 के साथ, क्यूटी 5.1.1 – Knitschi

+1

यदि आप 'QString' को' std :: string' में बदलते हैं तो यह काम करता है? – cmannett85

उत्तर

0

आप एक प्रति निर्माता जोड़ना चाहिए:

struct Parameter 
{ 
    QString stringPar; 
    Parameter& Parameter(const Parameter& rhs) 
    { 
     if((void*)this == (void*)&rhs) 
     { 
      return *this; 
     } 
     this->stringPar = rhs.stringPar; 
     return *this; 
    } 
}; 

एक अस्थायी पैरामीटर उदाहरण सी की वजह से जब आप ClassA :: समारोह (फोन बनाई गई है) ++ मूल्य से तर्क गुजर; कुछ इस तरह:

void ClassA::function(Parameter pars = QString("jkjsdghdkjhgdjufgskhdbfgskzh")) 
{ 
    m_string1 = pars.stringPar; // last line called in my code when the crash happens 
} 

आप एक प्रति निर्माता बारे में नहीं है, तो संकलक इस तरह एक डिफ़ॉल्ट प्रतिलिपि निर्माता संश्लेषण जाएगा:

Parameter& Parameter(const Parameter& rhs) 
    { 
     memcpy(this, &rhs, sizeof(Parameter)); 
     return *this; 
    } 

मुझे लगता है कि QString सूचक सदस्य हैं, यह मानते हुए यह नाम है ptr। फिर pars.stringPar.ptr और QString ("jkjsdghdkjhgdjufgskhdbfgskzh")। StringPar.ptr उसी स्मृति पते को इंगित करेगा। इस तरह

कॉल समारोह:

classA.function({ QString("jkjsdghdkjhgdjufgskhdbfgskzh") }); 

{QString ("jkjsdghdkjhgdjufgskhdbfgskzh")} वस्तु को नष्ट करने से पहले classA.function() वापसी, तो स्मृति {QString ("jkjsdghdkjhgdjufgskhdbfgskzh")} stringPar से इशारा किया।। पीआरटी मुक्त है, और pars.stringPar.ptr अमान्य स्मृति को इंगित करता है।

// when using this code the problem does not occur 
//Parameter par1 = { QString("jkjsdghdkjhgdjufgskhdbfgskzh") }; 
//classA.function(par1) 
//par1 destroy when main() function return, thus classA.function() does not crash. 

देखें < < प्रभावी सी ++ >> मद 11: गतिशील रूप से आबंटित स्मृति के साथ कक्षाओं के लिए एक प्रतिलिपि निर्माता और एक असाइनमेंट ऑपरेटर घोषित। प्रभावी सी ++, 2E http://debian.fmi.uni-sofia.bg/~mrpaff/Effective%20C++/EC/EI11_FR.HTM

+0

क्यूस्ट्रिंग में एक कॉपी-कन्स्ट्रक्टर और असाइनमेंट ऑपरेटर है। मैंने टिप्पणियों में उल्लेख किया कि समस्या को क्यूस्ट्रिंग के बजाय std :: string का उपयोग करके पुन: उत्पन्न किया जा सकता है। तो मैं वास्तव में नहीं देखता कि मुझे पैरामीटर संरचना के लिए अपनी खुद की प्रतिलिपि बनाने की आवश्यकता क्यों होगी क्योंकि डिफ़ॉल्ट एक ठीक होना चाहिए। "{QString (" jkjsdghdkjhgdjufgskhdbfgskzh ")} ऑब्जेक्ट classA.function() वापसी से पहले नष्ट हो जाता है ..."। मैंने सोचा कि समारोह तर्कों में अज्ञात चर को फ़ंक्शन रिटर्न मिलने तक लाइव रहने की गारंटी है, लेकिन शायद मैं गलत था। – Knitschi

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