删除别名指针

发布于 2024-12-06 07:30:35 字数 237 浏览 4 评论 0原文

这样做:

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

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

我认为如果这些类型中的任何一个具有不平凡的析构函数,这将不起作用,但是这样可以吗?

Doing this:

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

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

I assume this wouldn't work if any of these types have non trivial destructors, but is this ok?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

嗼ふ静 2024-12-13 07:30:36

如果我们假设“工作”意味着具有明确定义的行为而不是看起来可以工作(即不崩溃),那么在任何情况下这都行不通。

This doesn't work in any case, if we assume work means having well-defined behavior rather than appearing to work (i.e. not crashing)

无需解释 2024-12-13 07:30:36

不,无论该项目是否具有简单的析构函数,这都是未定义的行为。如果析构函数很简单,它可能看起来可以“工作”,而实际上它会泄漏内存等。

No, this is undefined behavior regardless of whether or not the item has a trivial destructor. If the destructor is trivial it may appear to "work" when in fact it's leaking memory, etc.

jJeQQOZ5 2024-12-13 07:30:36

我想说这是介于实现定义和未定义之间的某个地方。

5.3.5/2:“在第一个替代方案(删除对象)中,
delete 的操作数可能是...指向
由先前的 new 表达式创建的非数组对象....

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

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

I'm going to say this is somewhere between implementation defined and undefined.

5.3.5/2: "In the first alternative (delete object), the value of the
operand of delete may be ... a pointer to a
non-array object created by a previous new-expression ... .

The value of the pointer does not change when used the way you did so, so this should work as expected, provided sizeof(char*) == sizeof(int*). The result of that particular comparison is implementation defined, and if the assumption is false then the behavior is undefined.

So it really really isn't particularly safe.

假面具 2024-12-13 07:30:36

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

#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;

}

It is easy to see this is a dangerous error. The two types might have completely different and incompatible ways of memory allocation and deallocation. This includes padding, garbage collection, bookkeeping, class-specific memory manipulation, etc. Just don't do it.

#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;

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文