我正在为没有任何库的软件(内核)开发C ++编码。我对新运算符和删除运算符感到困惑。我已经实现了KMalloc()和KFree()。现在,我想知道以下编码是否可以在没有任何标准C ++库的情况下工作。
void *mem = KMalloc(sizeof(__type__));
Object *obj = new (mem) ();
如果这不起作用,那么我将如何在没有任何Std Lib的预分配空间中设置vtable或任何对象结构。
答案 0 :(得分:3)
首先应该定义您要定位的C ++标准。我想这至少是C ++ 11。
然后,如果您使用C ++编写某些操作系统内核代码,请注意并仔细研究相关的ABI规范(详细信息甚至取决于C ++编译器的版本,以及甚至异常处理和堆栈等血腥细节)放松很多事情)。
请注意,Linux内核ABI不是C ++友好的(它与x86-64的Linux用户登陆ABI不同)。因此,用C ++编写Linux内核编码是不合理的。
你可能想要
void *mem = KMalloc(sizeof(Object));
Object *obj = new (mem) Object();
第二个语句使用C ++的placement new功能,该功能将在(作为放置位置)传递的(或多或少“unitialized”)内存区域上运行构造函数。
(注意C ++对象的按位副本-eg与memcpy
- 一般是未定义的行为(除了POD s);你需要使用构造函数和赋值运算符)
没有“放置删除”,但您可以显式运行析构函数:obj->~Object()
,之后obj
指针所指向的对象的任何使用都是{{ 3}}。
现在,我想知道该代码是否可以在没有任何标准C ++库的情况下运行。
它可能比你所相信的要难得多。您需要了解编译器所针对的ABI的所有细节,这很难。
请注意,正确地运行 <{em> undefined behavior(和constructors) - 对于C ++来说是至关重要的。实际上,它们特别是初始化(隐式)destructors字段[s],没有它,你的对象就会崩溃(只要调用任何virtual
成员函数或析构函数)。
另请阅读vtable(适用于C ++ 11)。
用C ++编写自己的内核实际上需要了解有关C ++实现(和ABI)的许多细节。
注意:实际上,使用memcpy
智能指针的std::stream
进行按位复制,std::mutex
- s,std::thread
- es,std::string
- s - 甚至可能标准集装箱和this.
- 等等......很可能会造成灾难。如果你敢做这么糟糕的事情,你真的需要查看你的特定实现的细节......
答案 1 :(得分:2)
除了已经说过的其他答案之外,您可能需要重载operator new
和operator delete
,以便您无需执行KMalloc()
加展示位置new
一直欺骗。
// In the global namespace.
void* operator new
(
size_t size
)
{
/* You might also check for `KMalloc()`'s return value and throw
* an exception like the standard `operator new`. This, however,
* requires kernel-mode exception support, which is not that easy
* to get up and running.
*/
return KMalloc( size );
}
void* operator new[]
(
size_t size
)
{
return KMalloc( size );
}
void operator delete
(
void* what
)
{
KFree( what );
}
void operator delete[]
(
void* what
)
{
KFree( what );
}
然后,如有必要,可以通过调用KMalloc()
和KFree()
例程以及放置new
所需的所有构造函数来完成以下代码。
template<typename Type>
class dumb_smart_pointer
{
public:
dumb_smart_pointer()
: pointer( nullptr )
{}
explicit dumb_smart_pointer
(
Type* pointer
)
: pointer( pointer )
{}
~dumb_smart_pointer()
{
if( this->pointer != nullptr )
{
delete this->pointer;
}
}
Type& operator*()
{
return *this->pointer;
}
Type* operator->()
{
return this->pointer;
}
private:
Type* pointer;
};
dumb_smart_pointer<int> my_pointer = new int( 123 );
*my_pointer += 42;
KConsoleOutput << *my_pointer << '\n';