Static Order Problem?
-
Hallo, meine Anwendung stürzt in der "dbgdel.cpp"-Datei an Stelle
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));ab. Auf der Suche nach der Ursache habe ich die ganze Anwendung auf den beteiligten Code runtergebrochen. Verstehen tue ich es aber immer noch nicht.
Das Minimal-Konsolenprogramm könnt ihr hier runterladen:
https://rapidshare.com/files/460894194/Programm.rar
Genau genommen stürzt das Programm sogar zweimal ab. Das erste mal beim Aufruf derMember::MemberImpl::MemberImpl(const Info& ownerInfo)Funktion in der Member.cpp in der Zeile
Info info(ownerInfo);. Das zweite mal beim Beenden der Anwendung.
Woran kann das liegen? Static Order Fiasco? Oder doch ein Zeiger, Referenz die ins Nirvana zeigt?
Zum Programmablauf:
Die Klassen "Basic" und "Derived" haben jeweils eine statische Funktion "StaticInfo",Info& Derived::StaticInfo() { static Info info(Base::StaticInfo()); return info; }die eine Referenz auf ein "Info"-Object zurückgeben. Zusätzlich verweist ein Pointer des Info-Objects der Derived-Klasse auf das Info-Object der Base-Klasse.
Weiter hat die Derived-Klasse mehrere statische Member, die über die statische FunktionMember::Init(StaticInfo())initialisiert werden. Als Paramter wird dieser Funktion das Info-Object übergeben, das von der statischen Funktion StaticInfo() zurückgegeben wird.
In der Init-Funktion selber wird ein Member-Object erzeugt und zurückgegeben und einer statischen Liste hinzugefügt.std::vector<Member*>& Member::List() { static std::vector<Member*> list; return list; }Wenn es also wirklich ein Static Order Problem ist, dann müsste es doch bei der Initialisierung eines der statischen Member auftreten, da diese nicht wie die anderen statischen Objecte in Statische-Funktionen "eingelassen" sind. Allerdings rufen diese Member sich ja gar nicht gegenseitig auf. Bei der Initialisierung wird nur auf die statischen-Funktionen StaticInfo() und List() zugegriffen, die ja ihre Objekte beim ersten Aufruf erzeugen sollten. Darum glaube ich nicht, dass hier ein static order Problem vorliegt. Aber was verursacht den Absturz dann?
Achso, dass ich zwei mal das Pimpl-Idom verwenden muss lässt sich leider aus Designgründen nicht vermeiden. Sollte aber nicht das Problem sein.
-
SOP schrieb:
Auf der Suche nach der Ursache habe ich die ganze Anwendung auf den beteiligten Code runtergebrochen. Verstehen tue ich es aber immer noch nicht.
Das Minimal-Konsolenprogramm könnt ihr hier runterladen:Löblich. aber wenn der Code wirklich so weit runtergebrochen wurde, kannst du ihn auch gerne komplett hier posten. Die wenigsten werden zeit/Lust haben, sich das runterzuladen. Vom rapidshare-Account mal ganz zu schweigen. Wen du Hilfe möchtest machs uns nicht so schwer dir zu helfen

-
Das sind halt schon ein paar Dateien und einen Rapidshare-Account braucht man auch nicht. Habe ja selber keinen. Aber gut dann poste ich den Code mal.
-
Base.h
#ifndef BASE_H #define BASE_H #include "Info.h" class Base { public: Base(); static Info& StaticInfo(); }; #endifBase.cpp
#include "Base.h" Base::Base() { } Info& Base::StaticInfo() { static Info info; return info; }
-
Info.h
#ifndef INFO_H #define INFO_H class Info { public: Info(); Info(Info* baseInfo); ~Info(); private: class InfoImpl; InfoImpl* impl; }; #endifInfo.cpp
#include "Info.h" class Info::InfoImpl { public: InfoImpl(); InfoImpl(Info* baseInfo); Info* baseInfo; }; Info::InfoImpl::InfoImpl() : baseInfo(nullptr) { } Info::InfoImpl::InfoImpl(Info* baseInfo) : baseInfo(baseInfo) { } Info::Info() : impl(new Info::InfoImpl()) { } Info::Info(Info* baseInfo) : impl(new Info::InfoImpl(baseInfo)) { } Info::~Info() { delete impl; }
-
Member.h
#ifndef MEMBER_H #define MEMBER_H #include <vector> class Info; class Member { public: Member(); Member(const Info& ownerInfo); ~Member(); static Member& Init(const Info& ownerInfo); static std::vector<Member*>& List(); private: class MemberImpl; MemberImpl* impl; }; #endifMember.cpp
#include "Member.h" #include "Info.h" class Member::MemberImpl { public: MemberImpl(); MemberImpl(const Info& ownerType); ~MemberImpl(); Info ownerInfo; }; Member::MemberImpl::MemberImpl() { } Member::MemberImpl::MemberImpl(const Info& ownerInfo) : ownerInfo(ownerInfo) { //Hier stürzt das Programm ab Info info(ownerInfo); } Member::MemberImpl::~MemberImpl() { } Member::Member() : impl(new Member::MemberImpl()) { } Member::Member(const Info& ownerInfo) : impl(new Member::MemberImpl(ownerInfo)) { } Member::~Member() { delete impl; } Member& Member::Init(const Info& ownerInfo) { Member* member = new Member(ownerInfo); List().push_back(member); return *member; } std::vector<Member*>& Member::List() { static std::vector<Member*> list; return list; }
-
Derived.h
#ifndef DERIVED_H #define DERIVED_H #include "Member.h" #include "Base.h" class Derived : public Base { public: Derived(); static Info& StaticInfo(); protected: static Member m1; static Member m2; static Member m3; static Member m4; }; #endifDerived.cpp
#include "Derived.h" Member Derived::m1 = Member::Init(StaticInfo()); Member Derived::m2 = Member::Init(StaticInfo()); Member Derived::m3 = Member::Init(StaticInfo()); Member Derived::m4 = Member::Init(StaticInfo()); Derived::Derived() { } Info& Derived::StaticInfo() { static Info info(Base::StaticInfo()); return info; }
-
Main.cpp
#include <Windows.h> #include <iostream> #include "Derived.h" int main() { Derived d; std::wcout << L"Hello World!" << std::endl; while(true){}; return 0; }
-
Zu einer .c gehört eine .h und zu einer .cpp gehört eine .hpp!
-
Ok, das lässt sich ändern. Aber zurück zum eigentlichen Problem:
Member::MemberImpl::MemberImpl(const Info& ownerInfo) : ownerInfo(ownerInfo) { //Hier stürzt das Programm ab Info info(ownerInfo); }Warum nur?