删除别名指针

时间:2011-09-23 14:20:47

标签: c++ pointers unions delete-operator

这样做:

 union{
     int * integer;
     char * character;
 } u;
 u.integer = new int;
 delete u.character;

 u.integer = new int[5];
 delete [] u.character;

我认为如果这些类型中的任何一种具有非平凡的析构函数,这将无效,但这样可以吗?

4 个答案:

答案 0 :(得分:8)

在任何情况下都不工作,如果我们假设工作意味着有明确定义的行为而不是看似工作(即没有崩溃)

答案 1 :(得分:1)

不,无论项目是否具有普通的析构函数,这都是未定义的行为。如果析构函数是微不足道的,那么当它实际上是在泄漏内存等时,它可能出现到“工作”。

答案 2 :(得分:1)

我要说这是介于实现定义和未定义之间。

  

5.3.5 / 2:“在第一个备选(删除对象)中,值为   delete的操作数可以是...指向a的指针   由前一个新表达式创建的非数组对象....

当您按照这样做的方式使用时,指针的值不会改变,所以这应该按预期工作,前提是sizeof(char*) == sizeof(int*)。特定比较的结果是实现定义,如果假设为假,则行为未定义。

所以它确实不是特别安全。

答案 3 :(得分:0)

很容易看出这是一个危险的错误。这两种类型可能具有完全不同且不兼容的内存分配和释放方式。这包括填充,垃圾收集,簿记,特定于类的内存操作等。只是不要这样做。

#include <cstddef>
#include <cstdlib>
#include <iostream>

using namespace std;

class A
{

    public:

        void* operator new (size_t size)
        {
            cout << "A::operator new (size_t)" << endl;
            return malloc(size);
        }

        void* operator new [] (size_t size)
        {
            cout << "A::operator new [] (size_t)" << endl;
            return malloc(size);
        }

        void operator delete (void* ptr)
        {
            cout << "A::operator delete (void*)" << endl;
            free(ptr);
        }

        void operator delete [] (void* ptr)
        {
            cout << "A::operator delete [] (void*)" << endl;
            free(ptr);
        }

};

class B
{

    public:

        void* operator new (size_t size)
        {
            cout << "B::operator new (size_t) with some B-specific stuff" << endl;
            return malloc(size);
        }

        void* operator new [] (size_t size)
        {
            cout << "B::operator new [] (size_t) with some B-specific stuff" << endl;
            return malloc(size);
        }

        void operator delete (void* ptr)
        {
            cout << "B::operator delete (void*) with some B-specific stuff" << endl;
            free(ptr);
        }

        void operator delete [] (void* ptr)
        {
            cout << "B::operator delete [] (void*) with some B-specific stuff" << endl;
            free(ptr);
        }

};


int main (int, char**)
{

    union{
        A* a;
        B* b;
    } u;

    u.a = new A();
    delete u.b;

    u.a = new A[5];
    delete [] u.b;

}