C++ 应用程序,内存分配的途径

默认的内存分配方式

image.png

关于 ① 处的说明(成员函数的自定义内存分配)
可通过自定义内存池的方式提高使用效率,如更快的分配速度,更省的内存空间(省去 cookie)
关于 ② 处的说明 (重载全局空间的内存管理策略)
全局的内存管理策略会被多处有意或无意的使用,代码会大范围的收到影响,可重载但少见

容器的内存分配方式

image.png

  • 容器并未采用默认的内存管理方式,而采用内存分配器重新实现
  • 内存分配与构造被重新封装彼此分离
  • 内存释放与析构被重新封装彼此分离
Foo *p = (Foo)operator new(sizeog(Foo));  // 内存申请
new(p) Foo(x);                            // 构造
...
p->~Foo();                                // 析构
operator delete(p);                       // 内存释放

全局重载 ::operator new / ::operator delete

小心,影响无边无际!
void *myAlloc(size_t size)
{
    return malloc(size);
}

void myFree(void *ptr)
{
    return free(ptr);
}

void *operator new(size_t size)
{
    cout << "global new" << endl;

    return myAlloc(size);
}

void *operator new[] (size_t size)
{
    cout << "global new[]" << endl;

    return myAlloc(size);
}

void operator delete(void *ptr) noexcept
{
    cout << "global delete" << endl;

    myFree(ptr);
}

void operator delete[] (void *ptr) noexcept
{
    cout << "global delete" << endl;

    myFree(ptr);
}
operator new 的一种实现 [...\vc98\src\newop.cpp]
void *operator new(size_t size, const std::nothrow_t &_THROW0())
{
    // try to allocate size bytes
    void *p;
    while ((p == malloc(size)) == 0)
    {
        // buy more memory or return null pointer
        __TRY_BEGIN
            if (_callnewh(size) == 0) break;
        __CATCH(std::bad_alloc) return (0);
        __CATCH_END;
    }
    
    return (p);
}
operator delete 的一种实现 [...\vc98\src\delop.cpp]
void __cdecl operator delete(void *p) _THROW0()
{
    // free an allocated object
    free(p);
}

类内重载 operator new/operator delete

class Foo {
public:
    void *operator new(size_t);
    void operator delete(void*, size_t[可选]);
}

------------------------------

Foo *p = new Foo;
==>
try {
    void *mem = operator new(sizeof(Foo));
    p = static_cast<Foo*>(sizeof(Foo));
    p->Foo::Foo();
}

------------------------------

delete p;
==>
p->~Foo();
operator delete(p);
类内重载 operator new, operator delete 的成员函数具有 static 属性
非静态成员函数需要对象(隐藏的this指针)完成调用,而 operator new 被调用时表示对象正在被创建

类内重载 operator new[]/operator delete[]

class Foo {
public:
    void *operator new[](size_t);
    void operator delete[](void*, size_t[可选]);
    // ...
};

------------------------------

Foo *p = new Foo[N];
==>
try {
    void *mem = operator new(sizeof(Foo) * N + 4);
    p = static_cast<Foo*>(mem);
    p->Foo::Foo();    // N 次
}

------------------------------

delete[] p;
==>
p->~Foo();            // N 次
operator delete(p);
类内重载 operator new[], operator delete[] 的成员函数具有 static 属性
非静态成员函数需要对象(隐藏的this指针)完成调用,而 operator new[] 被调用时表示对象正在被创建

TianSong
737 声望139 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧