在没有 new[] 的情况下分配 Derived 数组:指向 Base vtable 的指针是错误的
基本上,我有一个纯虚拟类 Base 和一个继承自 Base 的具体类 Derived 。然后,我分配一块内存,并通过简单的转换将其视为 Derived 数组。然后,我使用 = 填充数组。最后,我循环遍历该数组,尝试调用在 Base 中声明并在 Derived 中定义的虚拟方法 GetIndex。
问题是,我最终在尝试读取 Base 的 vtable 指针时遇到访问冲突异常(在 Visual Studio 调试中,这显示为 __vfptr,并且始终为 0xbaadf00d)。
以下是我遇到的问题的一个简单示例:
#include "stdafx.h"
#include "windows.h"
struct Base
{
virtual int GetIndex() const = 0;
};
struct Derived : public Base
{
int index;
Derived()
{
static int test = 0;
index = test++;
}
int GetIndex() const
{
return index;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int count = 4;
// Also fails with malloc
Derived* pDerived = (Derived*)HeapAlloc(GetProcessHeap(), 0, sizeof(Derived) * count);
for (int i = 0; i < count; i++)
{
Derived t;
pDerived[i] = t;
}
// Should print 0 1 2 3
for (int i = 0; i < count; i++)
{
Base& lc = pDerived[i];
printf("%d\n", lc.GetIndex()); // FAIL!
}
return 0;
}
此行为仅在通过 HeapAlloc 或 malloc 分配内存时发生;如果使用 new[] ,则效果很好。 (此外,cstor 之前被调用了 4 次,因此输出为 4 5 6 7。)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您在没有
new
的情况下分配内存,则始终需要使用 placement new 和析构函数x->~Derived();
If you allocate memory without
new
you always need to call the constructor manually with placement new and the destructor withx->~Derived();
如果您想使用 C++ 默认分配器之外的分配器,您应该定义自己的运算符 new,而不是尝试记住每次都调用构造函数。
...
详细信息取决于您是否希望它成为分配
Derived
的默认方式以及它是否确实需要参数。如果
free()
无法释放您获得的内存,您仍然需要小心。那么默认的delete
将不起作用,您应该创建Derived::operator delete
或编写自己的函数来调用object->~Derived( )
。If you want to use an allocator besides C++'s default, you should define your own operator new rather than try to remember to call the constructor every time.
…
Details depend on whether you want it to be the default way of allocating
Derived
and whether it really needs parameters.You still need to be careful if
free()
can't free the memory you got. Then the defaultdelete
won't work, and you should either createDerived::operator delete
or write your own function which callsobject->~Derived()
.我认为在第一个 for 循环中,您正在创建一个没有 new 的对象。这意味着该对象的上下文是您的 for 循环。当退出 for 循环时,该变量不再存在。
I think inside the first for loop you are creating a object without new. Which means that the context of this object is your for loop. This variable no longer exists when you quit the for loop.