手动的内存分配导致类型失去一些信息

CaesireKin 2014-09-20 06:53:29
是这样滴额,最近我在写代码的时候遇到一个有点头疼的问题,就是当我用手动的内存方式为一个对象数组分配内存后,这个数组内的对象都会丢失部分的类型信息,下面是我出问题的代码,请高手赐教

//dec.h
#define class Interface
Interface A
{
public:
virtual int Process(void) = 0;
}

class B: protected A
{
public:
int Process(void) override;
}

//main.cpp
//...

int main(int argc,char** argv)
{
void* array_of_b = malloc(sizeof(B) * 10);
//下面这段代码会发现那张什么虚什么表(忘记名字了= =!)
//以及B的基类A的地址都是无效的,求解
B* bes = static_cast<B*>(array_of_b);

return 1;
}



大致的问题就像刚才给出的代码所指明的一样,原因在于我分配内存的时候绕过了构造函数的执行,所以不知有没有人有解决过这种问题的经验,我只需要一点提示和建议就好,谢谢
...全文
211 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Johnblx 2014-09-22
  • 打赏
  • 举报
回复
C++中还是不要使用malloc吧? 尤其是在做项目中,应该会有自己的内存管理模块? 内存管理模块式没有办法管理malloc函数的。
超级能量泡泡 2014-09-22
  • 打赏
  • 举报
回复
直接用new,而且必须递归到每个数组元素 存在虚函数的类,在new的时候构造就包含了一个特殊指针,也就包含了特定的类型信息。而这个过程在malloc时是没有的。
lm_whales 2014-09-22
  • 打赏
  • 举报
回复
placement new ?这个,不知道还是翻书吧
CaesireKin 2014-09-21
  • 打赏
  • 举报
回复
引用 5 楼 Idle_ 的回复:
这就是placement new,c++中new分成两部分,一部分分配内存,另一部分调用构造函数初始化对象。 c++中可以通过指定某块内存即上述写法忽略分配内存部分,只初始化对象。其实分配/释放内存部分可以通过operator new/operator delete让用户重载。c++中似乎并没有placement delete。因此placement new出来的对象不能用delete删除而是需要手工调用该类的析构函数,至于对应的内存则由程序另行处理。placement new和强制类型转换某块内存成类实例指针的区别就是强制类型转换略去了类的初始化而placement new则保证调用了类的构造函数。
原来是这样,我也一直在想placement new是不是被我误会了,昨晚一直没翻资料,多谢你的解释了
xiaohuh421 2014-09-21
  • 打赏
  • 举报
回复
void* array_of_b = malloc(sizeof(B) * 10); 你这里只分配了空间, 没有调用任何的构造函数, 怎么可能会有虚表呢? 你绕过构造函数的调用, 那你是想做什么呢? 自动手动生成虚表??? char *buffer = malloc(sizeof(char) * 16 + sizeof(unsigned int)) MyClass *clazz = new(buffer) MyClass; 这个和你的代码的区别大着呢. 关键在于后一句.MyClass *clazz = new(buffer) MyClass; 这句的意思就是在buffer上构造一个MyClass对象.
勤奋的小游侠 2014-09-21
  • 打赏
  • 举报
回复
引用 9 楼 chn3698 的回复:
[quote=引用 8 楼 Idle_ 的回复:] 啥编译器? 这个应该自动调用的是void* operator new[] (size_t, void*) throw();呀? 难道需要 #include <new> ?
VS2012 ,另外你不是说你的那种写法会调用 new(已分配的内存的指针)Class这样的new吗? 我也查了一些资料,并且看到有关于这个的内容,资料中的代码大致是这样的 char *buffer = malloc(sizeof(char) * 16 + sizeof(unsigned int)) MyClass *clazz = new(buffer) MyClass; 我的写法貌似和他没什么区别啊。。。请问怎么回事。。是我理解错了么?[/quote] operator new[] operate new 是两个不同的重载。建议楼主还是不要用malloc这种c的东西,好好研究placement new之类的比较实际一点。
阿呆_ 2014-09-21
  • 打赏
  • 举报
回复
先在cpp中加上#include <new>试试?
CaesireKin 2014-09-21
  • 打赏
  • 举报
回复
引用 8 楼 Idle_ 的回复:
啥编译器? 这个应该自动调用的是void* operator new[] (size_t, void*) throw();呀? 难道需要 #include <new> ?
VS2012 ,另外你不是说你的那种写法会调用 new(已分配的内存的指针)Class这样的new吗? 我也查了一些资料,并且看到有关于这个的内容,资料中的代码大致是这样的 char *buffer = malloc(sizeof(char) * 16 + sizeof(unsigned int)) MyClass *clazz = new(buffer) MyClass; 我的写法貌似和他没什么区别啊。。。请问怎么回事。。是我理解错了么?
阿呆_ 2014-09-21
  • 打赏
  • 举报
回复
啥编译器? 这个应该自动调用的是void* operator new[] (size_t, void*) throw();呀? 难道需要 #include <new> ?
阿呆_ 2014-09-21
  • 打赏
  • 举报
回复
引用 4 楼 chn3698 的回复:
[quote=引用 3 楼 Idle_ 的回复:] void* array_of_b = malloc(sizeof(B) * 10); B* bes = new(array_of_b) B[10];
谢谢。。不过我第一次见这种写法,能否解释下含义?[/quote] 这就是placement new,c++中new分成两部分,一部分分配内存,另一部分调用构造函数初始化对象。 c++中可以通过指定某块内存即上述写法忽略分配内存部分,只初始化对象。其实分配/释放内存部分可以通过operator new/operator delete让用户重载。c++中似乎并没有placement delete。因此placement new出来的对象不能用delete删除而是需要手工调用该类的析构函数,至于对应的内存则由程序另行处理。placement new和强制类型转换某块内存成类实例指针的区别就是强制类型转换略去了类的初始化而placement new则保证调用了类的构造函数。
CaesireKin 2014-09-21
  • 打赏
  • 举报
回复
引用 5 楼 Idle_ 的回复:
这就是placement new,c++中new分成两部分,一部分分配内存,另一部分调用构造函数初始化对象。 c++中可以通过指定某块内存即上述写法忽略分配内存部分,只初始化对象。其实分配/释放内存部分可以通过operator new/operator delete让用户重载。c++中似乎并没有placement delete。因此placement new出来的对象不能用delete删除而是需要手工调用该类的析构函数,至于对应的内存则由程序另行处理。placement new和强制类型转换某块内存成类实例指针的区别就是强制类型转换略去了类的初始化而placement new则保证调用了类的构造函数。
不过我刚才测试了一遍你的方法,我是这么写的: void* besChunk = malloc(sizeof(B) * 10 + sizeof(unsigned int)); B* bes = new(besChunk) B[10]; 有点照抄你的代码的嫌疑哈= =!不过毕竟测试,所以我就想先用你的试一试,但是, 编译器提示错误:无法使用给定参数列表调用operate new,参数类型(unsigned int,void*) 请问我是漏了什么没做吗?
CaesireKin 2014-09-20
  • 打赏
  • 举报
回复
引用 3 楼 Idle_ 的回复:
void* array_of_b = malloc(sizeof(B) * 10); B* bes = new(array_of_b) B[10];
谢谢。。不过我第一次见这种写法,能否解释下含义?
阿呆_ 2014-09-20
  • 打赏
  • 举报
回复
void* array_of_b = malloc(sizeof(B) * 10); B* bes = new(array_of_b) B[10];
CaesireKin 2014-09-20
  • 打赏
  • 举报
回复
引用 1 楼 brookmill 的回复:
我的建议就是不要绕过构造函数,不要用void*,不要用malloc要用new。 不过楼主既然这么写了想必也是有原因的。我在书上看到过placement new,说不定对楼主有用,不过我也没用过
我也有想过重载new运算符,不过还是想找找更好的解决方案
brookmill 2014-09-20
  • 打赏
  • 举报
回复
我的建议就是不要绕过构造函数,不要用void*,不要用malloc要用new。 不过楼主既然这么写了想必也是有原因的。我在书上看到过placement new,说不定对楼主有用,不过我也没用过

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧