更改基类指针内容而不分配新地址 我正在研究一个内存容量有限的ARDUINO项目,所以C++中有很多神奇的便利性,其中一个是能够在任何你想要的地方分配内存(如果你这样做的话)。但OOP需要指针和分配: class StateBase { virtual run(); }; class StateA : public StateBase { int bigArr[100]; virtual run(); }; //About 5 more States, with different member variables //Usually in Arduino, you allocate a big chunk of heap memory, and keep reusing it: StateBase *memPool[] = {new StateA(), new StateB(), new...};
但我想试试这个,令我惊讶的是,它是有效的:更改基类指针内容而不分配新地址 我正在研究一个内存容量有限的ARDUINO项目,所以C++中有很多神奇的便利性,其中一个是能够在任何你想要的地方分配内存(如果你这样做的话)。但OOP需要指针和分配: class StateBase { virtual run(); }; class StateA : public StateBase { int bigArr[100]; virtual run(); }; //About 5 more States, with different member variables //Usually in Arduino, you allocate a big chunk of heap memory, and keep reusing it: StateBase *memPool[] = {new StateA(), new StateB(), new...};,c++,oop,pointers,arduino,C++,Oop,Pointers,Arduino,但我想试试这个,令我惊讶的是,它是有效的: StateBase *memPool = new StateBase(); //...do something, now I need to switch state StateA newState; memcpy(memPool, &newState, sizeof(StateA)); 问题: 这是个坏主意吗?有什么后果吗 您是否应该使用memPool=new(memPool)StateA()而不是memcpy 很明显,StateBase和
StateBase *memPool = new StateBase();
//...do something, now I need to switch state
StateA newState;
memcpy(memPool, &newState, sizeof(StateA));
问题:
memPool=new(memPool)StateA()
而不是memcpysizeof
)。见1中的结果虽然这看起来很有效,但出于几个原因,这是个坏主意。一方面,由于编译器可以进行各种优化,您的代码可能会意外中断。更重要的是,您正在清除堆的一部分,因此程序崩溃可能只是时间问题。即使您对使用未定义的行为不太敏感,这也不安全。有些时候你可以做一些技术上可行但通常有效的事情,但是如果你正在覆盖未分配的内存,那么现在就不是这样了
如果你真的很担心碎片,你实际上可以使用你的选项2并做一个新的放置,但是无论你使用什么内存缓冲区都应该足够大以容纳你将要使用它的最大类对象。我也不会先换一个对象,然后再换另一个对象。那太乱了。只需使用malloc或其他方法单独分配缓冲区,然后在该地址上使用placement new。处理完对象后,显式调用析构函数,然后可以使用另一个新位置重用内存。冲洗并重复。由于StateA比StateBase大得多,因此您将写入超过分配的内存。这是允许的,但它不起作用,因为您可能正在覆盖其他数据。最终,当访问这些数据时,您将遇到问题。