美文网首页Exceptional C++
【Exceptional C++(20)】内存管理(二)

【Exceptional C++(20)】内存管理(二)

作者: downdemo | 来源:发表于2018-01-30 13:02 被阅读13次

问题

  • 找出下列代码中与内存有关的错误
class B {
public:
    virtual ~B();
    void operator delete(void*, size_t) throw();
    void operator delete[](void*, size_t) throw();
    void f(void*, size_t) throw();
};
class D : public B {
public:
    void operator delete(void*) throw();
    void operator delete[](void*) throw();
};
void f()
{
    // 下列语句中调用的是哪个delete
    // 调用时的参数是什么
    D* pd1 = new D;
    delete pd1;
    B* pb1 = new D;
    delete pb1;
    D* pd2 = new D[10];
    delete[] pd2;
    B* pb2 = new D[10];
    delete[] pb2;
    // 下面两个赋值语句合法吗?
    B b;
    typedef void (B::*PMF)(void*, size_t);
    PMF p1 = &B::f;
    PMF p2 = &B::operator delete;
}
class X {
public:
    void* operator new(size_t s, int)
    throw(bad_alloc) {
        return ::operator new(s);
    }
};
class SharedMemory {
public:
    static void* Allocate(size_t s) {
        return OsSpecificSharedMemAllocation(s);
    }
    static void Deallocatate(void* p, int i) {
        OsSpecificSharedMemDeallocation(p, i);
    }
};
class Y {
public:
    void* operator new(size_t s, SharedMemory& m)
    throw(bad_alloc) {
        return m.Allocate(s);
    }
    void operator delete(void* p, SharedMemory& m, int i)
    throw() {
        m.Deallocate(p, i);
    }
};
void operator delete(void* p) throw() {
    SharedMemory::Deallocate(p);
}
void operator delete(void* p, std::nothrow_t&) throw() {
    SharedMemory::Deallocate(p);
}

解答

  • B的delete有第二个参数而D没有,这是出于个人喜好,两种写法都可行
  • 两个类都提供了delete和delete[]却没有提供new和new[]
  • 调用的delete版本
    D* pd1 = new D;
    delete pd1; // D::operator delete(void*)
    B* pb1 = new D;
    delete pb1; // D::operator delete(void*)
    D* pd2 = new D[10];
    delete[] pd2; // D::operator delete[](void*)
    B* pb2 = new D[10];
    delete[] pb2; // 不可预料的行为
    // 传递给delete的指针静态类型必须与动态类型一样
  • 再看看下面赋值语句的问题
    B b;
    typedef void (B::*PMF)(void*, size_t);
    PMF p1 = &B::f;
    PMF p2 = &B::operator delete;
  • 第二个赋值语句不合法,void operator delete(void*, size_t) throw()不是B的成员函数,虽然看起来很像,new和delete总是静态的,即使不显式声明为static,总是把它们声明为static是个好习惯
class X {
public:
    void* operator new(size_t s, int)
    throw(bad_alloc) {
        return ::operator new(s);
    }
};
  • 这会产生内存泄漏,因为没有相应的placement delete
class SharedMemory {
public:
    static void* Allocate(size_t s) {
        return OsSpecificSharedMemAllocation(s);
    }
    static void Deallocatate(void* p, int i) {
        OsSpecificSharedMemDeallocation(p, i);
    }
};
class Y {
public:
    void* operator new(size_t s, SharedMemory& m)
    throw(bad_alloc) {
        return m.Allocate(s);
    }
  • 同理,这里没有对应的delete,如果用这个函数分配的内存放置对象的构造过程中抛出异常,内存就不会被正常释放,例如
SharedMemory shared;
...
new (shared) T; // if T::T() throws, memory is leaked
  • 这里内存还无法被安全删除,因为类中没有正常的operator delete
    void operator delete(void* p, SharedMemory& m, int i)
    throw() {
        m.Deallocate(p, i);
    }
};

这个delete完全没用,因为它从不会被调用

void operator delete(void* p) throw() {
    SharedMemory::Deallocate(p);
}
  • 这是一个严重错误,因为它将要删除那些被缺省的::operator new分配出来的内存而非SharedMemory::Allocate()分配的
void operator delete(void* p, std::nothrow_t&) throw() {
    SharedMemory::Deallocate(p);
}
  • 同理,这里的delete只会在new(nothrow)T失败时才被调用,因为T的构造函数会带着一个异常来终止,并企图回收那些不是SharedMemory::Allocate()分配的内存

相关文章

  • 【Exceptional C++(20)】内存管理(二)

    问题 找出下列代码中与内存有关的错误 解答 B的delete有第二个参数而D没有,这是出于个人喜好,两种写法都可行...

  • 2020-03-11 c++ book

    exceptional c++ style 中文版more exceptional c++ 中文版exceptio...

  • 【Exceptional C++(19)】内存管理(一)

    C++有几个不同的内存区域,用来存储对象或其他类型的值,每一个区域有其各自的特点 常量数据区(const data...

  • c++内存管理

    c++内存管理长文 c++内存管理

  • 内存管理

    内容包括: C++内存管理 Java内存管理 C++内存管理 内存分配方式 在C++中,内存分成5个区,分别是栈、...

  • 书签

    笔记 C++ PrimerEffective C++Exceptional C++Effective STLC++...

  • 书签

    笔记 C++ PrimerEffective C++Exceptional C++Effective STLC++...

  • Java GC

    概述 GC => 垃圾回收 = 回收可用空间 + 压缩内存 内存管理 手动内存管理 => C | C++ 自动内存...

  • C++之内存布局

    在C++之内存管理一文中,我们已经了解到C++的内存管理,这里介绍C++的典型内存布局结构。 1、总体来说,C/C...

  • C++ 内存分配和管理

    C++ 内存分配和管理

网友评论

    本文标题:【Exceptional C++(20)】内存管理(二)

    本文链接:https://www.haomeiwen.com/subject/wttczxtx.html