没有调用位置释放函数

Placement deallocation function is not called

本文关键字:释放 函数 位置 调用      更新时间:2023-10-16

我写的下面的代码必须调用位置释放和分配函数。

#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.
}

演示

5.3.4/22说N3797:

位置释放函数的声明与声明一个位置分配函数,如果它有相同的参数的数目,在参数转换(8.3.5)之后,所有除第一个参数类型外,其他参数类型相同。如果查找找到单个匹配的释放函数,该函数将被调用;否则,不会调用任何释放函数。

它不是实现在C++11或这是我的误解?

如果提供了特定于类的释放函数,则除非提供了带有一个或两个参数的特定于类的释放函数,否则未以作用域解析操作符为前缀的delete表达式是不规范的:

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

所以你需要:

  • 提供void operator delete[](void*);
  • 提供void operator delete[](void*, size_t);,或
  • write ::delete[] a .
A *a = new(5, 5) A[10]; 
A::operator delete[](a,5,5);

如果您想要访问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);
}