我正致力于使用C ++重构遗留的C代码,并且由于需要重构的代码量,我正在零碎地进行。重构的C ++代码通过malloc和值检索策略构建LegacyCAttribute结构。未重构的代码仍然使用旧的LegacyCAttribute结构。
如果我将get策略中的堆栈变量返回给调用代码,一切都很好。但是如果我将LegacyCAttribute *作为ValueStrategy类的成员变量,则调用代码核心转储。
此代码可以正常使用:
class ValueStrategy {
public:
LegacyCAttribute* get();
};
LegacyCAttribute* ValueStrategy::get()
{
LegacyCAttribute* attr = malloc(sizeof(LegacyCAttribute));
// Build attr here by malloc'ing more memory for attr value lists and values etc.
return attr;
}
当它尝试使用get:
返回的指针时,会在get调用者中导致核心转储class ValueStrategy {
public:
LegacyCAttribute* get();
LegacyCAttribute* m_attr;
};
LegacyCAttribute* ValueStrategy::get()
{
m_attr = malloc(sizeof(LegacyCAttribute));
// Build m_attr here by malloc'ing more memory for attr value lists and values etc.
return m_attr;
}
我知道当ValueStrategy对象被破坏时m_attr会消失,但是使用它指向的malloc()分配的内存在该破坏中没有得到自由,所以我不明白为什么调用代码在第二种情况下使用get()调用返回的指针而不是第一种情况崩溃。
更正 - 代码的第二个版本确实有效 - 它是核心转储,因为代码实际上是:
LegacyCAttribute* ValueStrategy::get()
{
if (m_attr == NULL)
{
m_attr = malloc(sizeof(LegacyCAttribute));
// Build m_attr here by malloc'ing more memory for attr value lists and values etc.
}
return m_attr;
}
我没有在ValueStrategy ctor中将m_attr初始化为NULL。
感谢所有回复你的人真棒!对不起噪音。
答案 0 :(得分:0)
C ++中的类默认是可复制的。如果它们包含指针,则会复制指针,但不会复制它们指向的指针。如果其中一个类实例的析构函数然后在指针(或free())上调用delete
,它将使另一个副本留下一个“悬空指针”,这将导致各种各样的头痛。
那就是说,请提供真实的代码,提炼成一个小而完整的例子。特别是LegacyCAttribute* attr = malloc(sizeof(LegacyCAttribute));
将不会编译为C ++,因为它缺少static_cast
。好吧,除非LegacyCAttribute
实际上是void
的别名,但完整的示例会显示出来。 :)