Qt: Este OK să utilizați QString ca membru în clasa excepțională

Dezvolt o excepție personalizată, în care aș avea nevoie de un membru QString. Ceva asemănător cu:

class MyException
{
private:
    const QString fDescription;

public:
    MyException(QString desc);
};

MyException::MyException(QString desc) : fDescription(desc)
{}

Când încerc să o folosesc:

if (isErrorEncountered)
{
    MyException e(QString("Descriptive message here..."));
    throw e;
}

I get a segmentation fault. The symptoms are similar as described here: Qt QString cloning Segmentation Fault

The SIGSEGV originates from QBasicAtomicInt::ref, coming from QString::QString(const QString &other).

Mi se pare că există o încercare de a copia un QString nevalid în cadrul unui constructor de copie. Înțelegerea mea este că QString păstrează un indicator al conținutului său atâta timp cât există o referință validă la acesta. Dacă se face o copie a exemplului MyException, nu este adevărat că instanța temporară a stack-ului nu a părăsit domeniul și copia ar trebui să reușească?

Când pun în aplicare MyException fără un membru QString, totul funcționează bine.

0
Am avut aceeași problemă, este ceva de-a face cu mecanismul implicit de partajare a QString - deși nu am ajuns niciodată în partea de jos a exactului. @Evgeni Da, așa ar fi char * ; dar asta nu are nimic de-a face cu întrebarea.
adăugat autor cmannett85, sursa
@TadejMali Am fost destul de norocoasă să am o limită de 1024 caractere impuse extern, așa că am aruncat ieșirea într-un char [1024] . Nu foarte clasic, dar bine pentru scopurile mele. Cu toate acestea, folosirea unui std :: string sau std :: wstring ar fi o idee mult mai bună.
adăugat autor cmannett85, sursa
Ați venit cu un exemplu minim al programului dvs. care aruncă eroarea așa cum este scris mai sus (patch-ul fDescription (value) pentru a citi fDescription (desc) apoi o capturează și iese cu qDebug() ? Un astfel de caz minim funcționează bine pentru mine. Urmați procesul de aici: sscce.org
adăugat autor HostileFork, sursa
@mat Vă mulțumim pentru avertisment despre tipo. Voi încerca, de asemenea, cu const &.
adăugat autor Tadej Mali, sursa
@ cbamber85 Cum ați rezolvat problema dvs.?
adăugat autor Tadej Mali, sursa
@hostilefork Da, SSCCE este o idee bună. Am încercat și până acum se pare că un plan, un exemplu simplu, chiar funcționează bine. În mod evident, va trebui să săpat mai adânc în pregătirea mesajului. +1 pentru indiciu.
adăugat autor Tadej Mali, sursa
Valoarea este un obiect global sau o greșeală în exemplul dvs. de excepție? Ești sigur că excepția este pentru acel QString? De ce constructorul dvs. de excepție nu ia const & ?
adăugat autor Mat, sursa
De ce nu-l taie codul std :: string ?
adăugat autor TeaOverflow, sursa

1 răspunsuri

Răspunsul la întrebare este "Da, un QString poate fi în siguranță membru al unei excepții".

Problemele pe care le-am întâlnit s-au datorat faptului că obiectul, care acționa ca sursă de date pentru fDescription , a avut un bug. A implementat o metodă getter:

class Source
{
private: QString fData;
public:  QString GetData(void) { this->fData; }  //There is a missing return
}

Desigur, rezultatul acestei convorbiri a fost valoarea aleatoare rămasă în stack în momentul respectiv și, prin urmare, SIGSEGV.

QString se comportă așa cum era de așteptat și cu o referință validă la acesta, nu există probleme în utilizarea acestuia în excepție.

Punctul exact în care SIGSEGV a fost ridicat a fost lăsarea sferei de aplicare a blocului try , unde se construiește o copie a excepției (rețineți: aruncați prin valoare, prindeți prin referință). Constructorul de copiere implicit încearcă să creeze o copie superficială a tuturor membrilor și nu reușește să acceseze referința nevalidă QString.

0
adăugat
+1 pentru demonstrarea valorii construirii unui caz simplu de reprograf simplu ... rețineți, de asemenea, puteți marca propriul dvs. răspuns ca fiind acceptat pentru a închide întrebarea!
adăugat autor HostileFork, sursa