繁体   English   中英

编译器或标准C ++库-新增和删除

[英]Compiler or Standard C++ Library - new and delete

我正在开发没有任何库的软件(内核)的C ++编码。 我对new运算符和delete运算符感到困惑。 我已经实现了KMalloc()和KFree()。 现在,我想知道如果没有任何标准C ++库,以下编码是否可以工作。

void *mem = KMalloc(sizeof(__type__));
Object *obj = new (mem) ();

如果这不起作用,那么我将如何设置vtable或预分配空间中没有任何标准库的任何对象结构。

首先,您应该定义您要针对的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新功能,它将在作为placement传递的(或多或少的“单元化”)内存区域上运行构造函数。

(请注意,C ++对象的按位复制(例如,使用memcpy通常是未定义的行为( POD除外);您需要使用构造函数和赋值运算符)

没有“放置删除”,但是您可以显式运行析构函数: obj->~Object()之后对obj指针指向的对象的任何使用都是未定义的行为

现在,我想知道在没有任何标准C ++库的情况下该代码是否可以工作。

这可能比您相信的要难得多。 您需要了解编译器所针对的ABI的所有细节,这很难。

注意,以足够好的顺序正确运行构造函数 (和析构函数 )对于C ++至关重要。 实际上,他们特别是在初始化(隐式) vtable字段,否则,对象可能会崩溃(一旦调用任何virtual成员函数或析构函数,则该对象会崩溃)。

另请阅读有关5规则 (对于C ++ 11)。

用C ++编写自己的内核实际上需要了解有关C ++实现(和ABI)的许多细节。

注意:实际上,使用智能指针, std::stream -s, std::mutex -es, std::thread -s甚至是标准容器和std::string memcpy进行按位复制s等...-很可能造成灾难。 如果您敢于做这些坏事情,那么您确实需要研究特定实现的细节...

除了已经给出的其他答案之外,您可能还想重载operator newoperator 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()例程以及所有必需的构造函数(如placement new KMalloc() KFree()

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';

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM