访问冲突读取位置0x000000004

jiy*_*iyi 1 c++ access-violation visual-c++

我正在Visual Studio中进行C++编码练习,并将此问题显示为标题.我知道问题发生在哪里,但我不知道为什么会发生这种情况以及如何解决问题.请帮我解决一下这个.

class_templete.h

typedef std::string QuestionName;
class ClassTemplete
{
public:
    ClassTemplete(Question iQuestionName);
private
    static std::map<QuestionName,ClassTemplete *> questionName_questionPointer_map_;
}
Run Code Online (Sandbox Code Playgroud)

class_templete.cpp

map<QuestionName, ClassTemplete *> ClassTemplete::questionName_questionPointer_map_;

ClassTemplete::ClassTemplete(QuestionName iQuestionName)
{
    ClassTemplete::questionName_questionPointer_map_[iQuestionName] = this;
}
Run Code Online (Sandbox Code Playgroud)

chapter1_question1.h

class C1Q1 : public ClassTemplete
{
public:
    C1Q1(QuestionName iQuestionName) : ClassTemplete(iQuestionName) {};
private:
    static QuestionName question_name_;
    static C1Q1 question_instance_;
}
Run Code Online (Sandbox Code Playgroud)

chapter1_question1.cpp

QuestionName C1Q1::question_name_ = "C1Q1";
C1Q1 C1Q1::question_instance_(C1Q1::question_name_);
Run Code Online (Sandbox Code Playgroud)

当我运行程序时,我发现问题发生在这个地方:

ClassTemplete::questionName_questionPointer_map_[iQuestionName] = this;
Run Code Online (Sandbox Code Playgroud)

但是,我无法解释为什么会发生这种情况.

如果需要更多信息,请随时与我联系.

亲切的问候,

易记

Die*_*ühl 5

其中QuestionName C1Q1:::question_name_位于相对ClassTemplate::questionName_questionPointer_map_?它们似乎都是具有静态存储持续时间的变量,即它们在main()运行之前构造.但是,C++编译器/链接器仅使用一个转换单元(在这种情况下,对象从上到下构建)来排序此类全局对象的构造,而不是在转换单元之间(在这种情况下,对象以随机顺序构造).

您的问题看起来好像ClassTemplate::questionName_questionPointer_map将在之后构建C1Q1::question_name_.也就是说,当C1Q1::question_name_构造时,正在访问尚未构造的对象.

传统的解决方法是使static对象的其他对象依赖于对象,而是与本地函数static返回变量到的引用:

std::map<QuestionName,ClassTemplete *>&
ClassTemplete::questionName_questionPointer_map_() {
    static std::map<QuestionName,ClassTemplete *> rc;
    return rc;
}
Run Code Online (Sandbox Code Playgroud)

(请注意,当您不使用C++ 11时,此构造不是线程安全的;使用C++ 11时它线程安全的).