【问题标题】:overload delete[] operator to allow shrinkable arrays of types with destructor重载 delete[] 运算符以允许具有析构函数的可收缩类型数组
【发布时间】:2014-10-16 00:27:27
【问题描述】:

我们正在尝试重载 delete[] 运算符以实现shrinkable oriented to objects arrays

它适用于没有特定析构函数的数据类型。

当数据类型有指定的析构函数时,new[]操作符需要额外的字节。

您能帮我们回答这些问题吗?

  1. 为什么 new[] 运算符对于具有特定析构函数的数据类型需要额外的字节?
  2. new[] 运算符总是会请求这些字节还是依赖于库?
  3. 是否可以通过 if 语句知道数据类型是否具有特定的析构函数?

代码在尝试缩小 B 的数组时应该抛出一个未处理的异常。

#include<cstdlib>
#include<iostream>
using namespace std;

void*operator new[](size_t s){
    cout<<"Block size: "<<s<<endl;
    return malloc(s);
}
void operator delete[](void*p){
    free(p);
}
void operator delete[](void*p,size_t s){
    //Is it possible to know if the data type has a specific destructor?
    bool destructor=0;
    if(destructor){
        p=(char*)p-8,s+=8;
    }
    cout<<"New block size: "<<s<<endl;
    if(realloc(p,s)!=p)throw 0;
}

struct A{
    char a;

    A():a(0){}
    ~A()=default;
};

struct B{
    char b;

    B():b(0){}
    ~B(){}
};

int main(){
    unsigned S=10,s=4;
    cout<<"Creating "<<S<<" A's"<<endl;
    A*a=new A[S];
    cout<<"Creating "<<S<<" B's"<<endl;
    B*b=new B[S];
    cout<<"Shrinking A to "<<s<<" elements"<<endl;
    operator delete[](a,sizeof(A)*s);
    cout<<"Shrinking B to "<<s<<" elements"<<endl;
    operator delete[](b,sizeof(B)*s);
    cout<<"Deleting A and B"<<endl;
    delete[]b,delete[]a;
    return 0;
}

相关回答问题:

overload delete[] operator with specific arguments

【问题讨论】:

  • 我认为新运营商所需的任何额外空间都是实现定义的,依赖它是一个坏主意。为什么在 if 语句中使用 , 运算符而不是 {}?这不是常见的做法。
  • “你的 if 语句用运算符而不是 {}”我不明白你的意思 :(
  • 您发布的代码的预期行为是什么? ideone.com/9KkWFE
  • 如果您可以使用 C++11,也许这会有所帮助? en.cppreference.com/w/cpp/types/is_destructible
  • @nocom throwimg 异常是针对可恢复的错误。如果非平凡可复制类的内存在没有警告的情况下移动,则这是一个不可恢复的错误。在这种情况下,您应该终止程序,而不是抛出。另请注意,您可能需要弄清楚对象会发生什么:您的 delete 应该首先销毁,现在我考虑了一下,所以可能 realloc 无关紧要。但这意味着你需要重建。

标签: c++ operator-overloading realloc delete-operator


【解决方案1】:

这可以回答 12

当使用new操作符创建一个新数组时,通常会使用一个cookie 存储以记住分配的长度(数组元素的数量)所以 它可以被正确释放。

具体来说:

No cookie is required if the array element `type T` has a trivial destructor.

这意味着:

  • 因为结构 A 有一个简单的析构函数,所以它不需要 饼干。
  • 由于结构 B 有一个特定的析构函数,它需要一个 sizeof(size_t) 字节的 cookie,该 cookie 存储在数组的左侧。

参考:Itanium C++ ABI

【讨论】:

    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    相关资源
    最近更新 更多