C++构造奇怪的未初始化指针

Posted

技术标签:

【中文标题】C++构造奇怪的未初始化指针【英文标题】:C++ construction weird uninitialized pointer 【发布时间】:2008-11-04 23:43:33 【问题描述】:
AlertEvent::AlertEvent(const std::string& text) :
    IMEvent(kIMEventAlert, alertText.c_str()),
    alertText(text)

    //inspection at time of crash shows alertText is a valid string



IMEvent::IMEvent(long eventID, const char* details)

    //during construction, details==0xcccccccc

在相关说明中,等宽字体在 chrome 中看起来非常糟糕,这是怎么回事?

【问题讨论】:

【参考方案1】:

alertText 可能在调试器中显示为字符串,但尚未构造(因此 alertText.c_str() 将返回一个不确定的指针)。

为避免这种情况,可以初始化使用 text.c_str() 作为 IMEvent ctor 的参数。

AlertEvent::AlertEvent(const std::string& text) :
    IMEvent(kIMEventAlert, text.c_str()),
    alertText(text)

    //inspection at time of crash shows alertText is a valid string



IMEvent::IMEvent(long eventID, const char* details)

    //during construction, details==0xcccccccc

【讨论】:

初始化列表中值的顺序是无关紧要的。成员变量将按照它们在类中声明的顺序进行初始化。 第二:第一个建议的修复不起作用,并且“应该”引发编译器警告,因为它会导致初始化表达式以与它们不同的顺序被逆直觉地评估重新上市。 第二个建议的修复可能合适,也可能不合适,这取决于 IMEvent::IMEvent 对其 details 参数的作用。如果它把它藏起来,并期望它持续的时间比调用 AlertEvent::AlertEvent 返回的时间长,那么你可能不走运。【参考方案2】:

在调用 alertText 的构造函数之前调用 IMEvent 构造函数。因此,特别是它的参数alertText.c_str() 在调用 alertText 的构造函数之前被评估。这不好。

Initializer 表达式是按照声明被初始化的事物的顺序调用的(不一定是列出初始化程序的顺序)。所以首先是父类,然后是成员。如果您没有按照初始化程序实际执行的顺序列出初始化程序,编译器有时会向您发出警告。所以只要你做对了,规则是“不要使用你没有初始化的任何东西”。此代码在初始化之前使用了 alertText。

【讨论】:

【参考方案3】:

在调用 alertText 的构造函数之前调用 IMEvent 构造函数。

几乎。 alertText.c_str() 在构造 alertText 之前被调用,这是真正的问题。最简单的解决方案是将其替换为text.c_str()

【讨论】:

当然,但我猜测错误的假设是 alertText 已在使用点初始化。无论如何,我已将此添加到我的答案中,谢谢。

以上是关于C++构造奇怪的未初始化指针的主要内容,如果未能解决你的问题,请参考以下文章

valgrind 抱怨 C++ 结构上的未初始化字节

C++对象数组与对象指针

C++ 初始化作为对象指针容器的成员变量

关于结构的未初始化指针分配的语义

在 C++ 中使用指针和指向指针参数的指针创建构造函数

用向量 c++ 中的指针成员初始化对象