我对dynamic_cast如何将数组的元素强制转换为更大的类感到好奇(它会将所有其他元素都移位了吗?)。所以我写了一个小代码来尝试。但是我很惊讶,因为它在第一行只是编译而出现段错误。为什么呢
#include <iostream>
class A
{
public:
virtual ~A() {}
};
class B : public A
{
public:
int x;
};
class C : public A
{
public:
int x;
int y;
};
int main()
{
A* aArray = new B[2];
(dynamic_cast<B&>(aArray[0])).x = 1; //segfault here
(dynamic_cast<B&>(aArray[1])).x = 2;
(dynamic_cast<C&>(aArray[0])).y = 3;
std::cout << (dynamic_cast<B&>(aArray[1])).x << std::endl;
return 0;
}
最佳答案
我来啦。我编译并运行了gdb
首先,我设置打印对象选项:
(gdb) set print object
检查一个数组的地址
(gdb) print aArray
$1 = (B *) 0x8003a404
检查A和B的大小
(gdb) print sizeof(B)
$2 = 8
(gdb) print sizeof(A)
$3 = 4
获取aArray的地址[0]
(gdb) print &aArray[0]
$4 = (B *) 0x8003a404
获取aArray的地址[1]
(gdb) print &aArray[1]
$5 = (A *) 0x8003a408
引用answer in linked question:
和
在这种特定情况下,指针算法的实现是通过指针类型的大小来增加指针内存(但请引用此answer以获取更多细微差别)。
aArray + 1
的作用是指向类型A的对象数组的第二个元素符合:
(gdb) print (A*)(((char *)aArray) + sizeof(A))
$6 = (A *) 0x8003a408
...但是
aArray
实际上是B型对象的数组。因此,数组的第二个元素是:
(gdb) print &((B *)aArray)[1]
$6 = (B *) 0x8003a40c
因此您最终指向第一个B对象中间的某处...而该访问导致了分段错误。
有关替代说明的示例,请参见:[http://www.parashift.com/c++-faq/array-derived-vs-base.html]
关于c++ - 启用了RTTI的dynamic_cast segfault,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24187390/