C 多重继承和向上的智能指针破坏会导致VS 2017中的堆腐败
C++ multiple inheritance and upcasted smart pointer destruction causes heap corruption in VS 2017
我遇到了vs debugger的问题,上面的代码:
class Animal {
public:
};
class Stupid {
public:
};
class Dog : public Stupid, public Animal {
public:
};
int main() {
std::unique_ptr<Animal> animal = std::unique_ptr<Dog>(new Dog());
animal.reset();
return 0;
}
此代码在执行涉及" ntdl.dll"answers" wntdll.pdb"的" andial.reset(("之后会引发错误。
这是MSVC运行时库生成断言失败的表达式,如果我点击了"忽略"多(3(次:
1- _CrtIsValidHeapPointer(block)
2- is_block_type_valid(header->_block_use)
3- HEAP CORRUPTION DETECTED: before Free block (#-50331640) at 0x03737E21. CRT detected that the application wrote to memory before start of heap buffer.
但是,如果我更改狗的继承顺序,则是这样:
class Dog : public Animal, public Stupid {
public:
};
代码运行正常。
我只有在Visual Studio 2017中才有此错误,我尝试使用Ideone,Android Studio,无论继承顺序如何。
这断开了,因为您将您传递给delete
的指针与从new
返回的指针不同。
上铸造基本上意味着您将指针衍生为衍生,并假装它是指指底座。对于单个继承,这只是可行的,因为基础部分始终是存储在派生对象中的第一件事。但是有了多个继承,您有两个基础!
因此,当您对第二个底座进行铸造时,您需要更改指针的值,以确保指向它的指向实际上将是对象的各自的基数部分。您可以通过检查调试器中的指针值来验证这一点:
Dog* d = new Dog;
Animal* a = d;
a
指针将指向d
指针后面的一个字节。
如前所述,可以通过在删除呼叫中使用的基类类型中添加虚拟破坏者(示例中的Animal
(来解决此问题。这将导致编译器生成其他代码以正确调整指针,然后再将其传递给delete
。
请注意,GCC实际上在此处实现了空基类优化,因此此示例将在此工作。两个基地都将生活在相同的偏移量中。它将开始在此处分解,并且一旦您开始在基本类中添加非静态数据成员。
相关文章:
- VS 2017 使用交叉编译器构建 x64 项目
- 点云库在VS 2019中不起作用,但在VS 2017中确实有效
- 代码在Visual Studio 2017中不起作用,但在VS代码中工作
- VS 2017 和 2019 运行 c++ 真的很慢
- VS 2017 社区收到链接器错误,但专业版没有
- 如何知道C2259 VS 2017错误未实现哪种方法?
- 自定义构建文件更改不会触发VS 2017中的项目重建
- VS 2017 C++编译器在 VS 2005 中找不到匹配函数
- 当为模板参数提供默认参数时,VS 2017无法正确找到以前定义的类型
- 在VS 2017中,朋友通过具有私有析构函数的结构的unique_ptr向量进行迭代失败
- VS 2017 C++ - "cannot open source file 'sqlite3.h' "
- VS 2017 中的 CMake 在构建时不显示构建日志
- VS 2017 错误 C2664 地图插入尝试
- VS 2017 CMake 无法识别宏
- VS 2008 和 VS 2017 中静态参数的不同行为
- MFC 对话框属性表用法在 VS 2017 中产生错误,适用于 VS 2013
- VS 2017 构建工具失败,出现错误 MSB4019:找不到导入的项目"D:Microsoft.Cpp.Default.props"
- C vs 2017设置全局变量 - 程序仅在调试中使用断点
- std::get_time 在 VS 2017 中无法正常工作
- 命名空间从VS 2017转换为2012年