不调用放置释放功能

时间:2014-07-29 15:23:23

标签: c++ c++11 memory-management

我编写的以下代码必须同时调用放置释放和分配函数。

#include <iostream>
using namespace std;

struct A
{
    void * operator new [] (size_t t, int, int)
    {
        cout << "3 parameters allocation" << endl;
        return ::operator new[](t);
    }

    void operator delete [] (void *p, int, int)
    {
        cout << "3 parameters deallocation" << endl;
        return ::operator delete[](p);
    }
};

int main() 
{
    A *a = new (5,5) A[10]; //operator new [] (size_t, int, int) invoked
    delete [] a; //Error. Overload resolution is failed.
}

demo

5.3.4 / 22说N3797:

  

展示位置释放函数的声明与   如果具有相同的位置分配功能的声明   参数数量,参数变换后(8.3.5)全部   参数类型除了第一个是相同的。如果查找找到了   单匹配解除分配函数,该函数将被调用;   否则,不会调用释放函数。

这不是C++11中的实现,还是我的误解?

3 个答案:

答案 0 :(得分:9)

如果提供了特定于类的释放函数,则除非具有一个或两个参数的特定于类的释放函数,否则未通过作用域解析运算符作为前缀的 delete-expression 格式不正确可用的:

  

10 - 如果类型完成并且如果解除分配函数查找同时找到通常的释放函数,只有指针参数和通常的释放函数同时具有指针参数和大小参数,那么所选的释放函数应该是一个有两个参数。否则,所选的释放函数应为具有一个参数的函数

所以你需要:

  • 提供void operator delete[](void*);
  • 提供void operator delete[](void*, size_t);
  • ::delete[] a

答案 1 :(得分:1)

A *a = new(5, 5) A[10]; 
A::operator delete[](a,5,5);

在Visual C ++ 2013上,这非常有用

答案 2 :(得分:1)

如果您想要访问operator delete中的原始展示位置新参数,则必须将它们存储在已分配的内存块中,然后再检索它们。例如(Live at Ideone):

struct A
{
    static void * operator new [] (size_t t, int first, int second);
    static void operator delete [] (void *p, size_t t);
    static void operator delete [] (void *p, int first, int second)
    {
        cout << "3 parameters deallocation: " << first << ", " << second << endl;
        return ::operator delete[](p);
    }
};

// simple POD struct to store the placement parameters
struct info {
    int first_param, second_param;
};

void* A::operator new [] (size_t t, int first, int second)
{
    cout << "3 parameters allocation: " << first << ", " << second << endl;
    // allocate sizeof(info) extra space to store the parameters
    auto const p = ::operator new[](t + sizeof(info));
    auto const pinfo = reinterpret_cast<char*>(p) + t;
    auto const tmp = info{first, second};
    std::copy_n(reinterpret_cast<const char*>(&tmp), sizeof(info), pinfo);
    return p;
}

static void A::operator delete [] (void *p, std::size_t t) {
    // retrieve the parameters that we stored in operator new [].
    auto const pinfo = reinterpret_cast<const char*>(p) + t;
    auto tmp = info{};
    std::copy_n(pinfo, sizeof(info), reinterpret_cast<char*>(&tmp));
    cout << "Deleting with original parameters: " << tmp.first_param << ", " << tmp.second_param << endl;
    ::operator delete[](p);
}