c – 使用放置新[]有什么问题?做

前端之家收集整理的这篇文章主要介绍了c – 使用放置新[]有什么问题?做前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑下面的程序.它已经从一个复杂的案例中简化了.除非删除Obj类中的虚析构函数,否则它将无法删除先前分配的内存.我不明白为什么程序输出中的两个地址不同,只有虚拟析构函数存在时才会出现.
// GCC 4.4
#include <iostream>

using namespace std;

class Arena {
public:
    void* alloc(size_t s) {
        char* p = new char[s];
        cout << "Allocated memory address starts at: " << (void*)p << '\n';
        return p;
    }

    void free(void* p) {
        cout << "The memory to be deallocated starts at: " << p << '\n';
        delete [] static_cast<char*> (p); // the program fails here
    }
};

struct Obj {
    void* operator new[](size_t s,Arena& a) {
        return a.alloc(s);
    }

    virtual ~Obj() {} // if I remove this everything works as expected

    void destroy(size_t n,Arena* a) {
        for (size_t i = 0; i < n; i++)
            this[n - i - 1].~Obj();
        if (a)
            a->free(this);
    }
};


int main(int argc,char** argv) {
    Arena a;

    Obj* p = new(a) Obj[5]();
    p->destroy(5,&a);

    return 0;
}

这是虚拟析构函数存在时我的实现中程序的输出

Allocated memory address starts at: 0x8895008
The memory to be deallocated starts at: 0x889500c

RUN Failed (exit value 1)

请不要问它应该做什么程序.正如我所说,它来自一个更复杂的案例,其中Arena是各种类型内存的接口.在这个例子中,内存只是从堆中分配和释放.

解决方法

这不是新行返回的指针char * p = new char [s];您可以看到大小超过5个Obj实例.差异(应该是sizeof(std :: size_t))在附加内存中,包含数组的长度,5,紧接在其中包含的地址之前.

好的,规范说清楚了:

http://sourcery.mentor.com/public/cxx-abi/abi.html#array-cookies

2.7 Array Operator new Cookies

When operator new is used to create a new array,a cookie is usually stored to remember the allocated length (number of array elements) so that it can be deallocated correctly.

Specifically:

No cookie is required if the array element type T has a trivial destructor (12.4 [class.dtor]) and the usual (array) deallocation function (3.7.3.2 [basic.stc.dynamic.deallocation]) function does not take two arguments.

因此,析构函数的虚拟性是无关紧要的,重要的是析构函数是非平凡的,您可以通过删除析构函数前面的关键字virtual并观察程序崩溃来轻松检查.

原文链接:https://www.f2er.com/c/119091.html

猜你在找的C&C++相关文章