首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用placement new[]有什么问题?做

使用placement new[]有什么问题?做
EN

Stack Overflow用户
提问于 2011-11-24 20:44:53
回答 2查看 312关注 0票数 7

请考虑下面的程序。它已经从一个复杂的案例简化了。除非我删除Obj类中的虚拟析构函数,否则它在删除先前分配的内存时失败。我不明白为什么程序输出中的两个地址不同,只有在虚拟析构函数存在的情况下。

代码语言:javascript
复制
// 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;
}

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

分配的内存地址从: 0x8895008开始,要释放的内存从: 0x889500c开始。

运行失败(退出值1)

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-24 20:55:12

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

好的,规范明确了:

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

2.7阵列算子新Cookies

当使用运算符new创建一个新数组时,通常会存储cookie来记住分配的长度(数组元素的数量),以便能够正确地释放它。

具体地说:

如果数组元素类型T有一个平凡的析构函数(12.4 class.dtor),而通常的(数组)解分配函数(3.7.3.2 basic.stc.dynamic.deallocation)不带两个参数,则不需要cookie。

因此,析构函数的虚拟性是无关紧要的,重要的是析构函数是非平凡的,您可以很容易地检查它,方法是删除析构函数前面的关键字virtual并观察程序崩溃。

票数 5
EN

Stack Overflow用户

发布于 2011-11-24 21:28:08

根据寒冷的答案,如果你想让它“安全”:

代码语言:javascript
复制
#include <type_traits>

a->free(this - (std::has_trivial_destructor<Obj>::value ? 1 : 0));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8262312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档