当类型化的void指针指向对象时,析构函数不会被调用

时间:2021-05-27 20:13:52

Sample

void func(void* data)
{
 CResource* resource = (CResource*)data;
 delete resource; // ~CResource never called.
 resource = NULL;
}

Kindly help me to figure out this.

请帮我弄明白这一点。

7 个解决方案

#1


11  

Summarized possible reasons why CResource destructor may be not called, extracted from other answers:

总结了可能无法调用CResource析构函数的原因,从其他答案中提取:

Incomplete type

One possible cause is you have the CResource type only declared, not defined:

一个可能的原因是您只声明了CResource类型,未定义:

class CResource;

void func(void* data)
{
 CResource* resource = (CResource*)data;
 delete resource; // ~CResource never called.
 resource = NULL;
}

This is an undefined behaviour (deleting incomplete type). In a case like this compiler should issue a warning about destructor not called (Visual C++ definitely does issue it). If this is the case, make sure you have the type defined at the place where you are destructing it (include required headers).

这是一个未定义的行为(删除不完整的类型)。在这样的情况下,编译器应该发出关于未调用析构函数的警告(Visual C ++肯定会发出它)。如果是这种情况,请确保在要销毁它的位置定义了类型(包括所需的标题)。

NULL pointer

If data is NULL, delete does nothing and does not call any destructor.

如果data为NULL,则delete不执行任何操作,也不会调用任何析构函数。

Type mismatch

If CResource destructor is virtual and the object stored on memory pointed to by data is actually a different type, you get an undefined behavior. Often a different destructor will be called (if the object has another virtual destructor), in other situations the program may crash (if the object has no virtual destructor).

如果CResource析构函数是虚拟的,并且存储在数据指向的内存中的对象实际上是不同的类型,则会得到未定义的行为。通常会调用不同的析构函数(如果对象具有另一个虚拟析构函数),在其他情况下程序可能会崩溃(如果对象没有虚拟析构函数)。

#2


6  

The only reason, why the destructor wouldn't be called, is if the data pointer is 0 (or NULL). That's how delete works - it checks if the pointer isn't 0, and if it isn't - it calls the necessary destructors and releases the memory.

导致析构函数不被调用的唯一原因是数据指针是0(或NULL)。这就是删除的工作原理 - 它检查指针是否为0,如果不是,则调用必要的析构函数并释放内存。

As pointed out in the comment. There is another reason why it wouldn't get called. If data points to some other class (not CResource) object and both classes have virtual destructors, then the destructor of that other class will be called.

正如评论中指出的那样。另一个原因是它不会被调用。如果数据指向其他类(而不是CResource)对象,并且两个类都有虚拟析构函数,那么将调用该另一个类的析构函数。

#3


3  

Is the destructor virtual? Maybe data doesn't point to a CResource object at all and the virtual destructor of some other class is being called.

析构函数是虚拟的吗?也许数据根本不指向CResource对象,并且正在调用其他类的虚拟析构函数。

#4


2  

class Aardvark
{
public:
    virtual ~Aardvark()
    {
        printf("Aardvark::~Aardvark\n");
    }
};

class CResource
{
public:
    virtual ~CResource()
    {
        printf("CResource::~CResource\n");
    }
};

void func(void* data)
{
    CResource* resource = (CResource*)data;
    delete resource; // ~CResource never called.
    resource = NULL;
}

int _tmain()
{
    void *data = new Aardvark();
    func( data );
    return 0;
}

#5


0  

Destructor is called.Give us the full code.

调用析构函数。给我们完整的代码。

#6


0  

Why are you saying dtor is not called? Probably because you added a printf in your dtor, and you're not seeing any message?

你为什么说不叫dtor?可能是因为你在你的dtor中添加了printf,而你没有看到任何消息?

Probably another dotr is invoked? Is CResource inherited? Di you define the base class destructor virtual?

可能还会调用另一个dotr? CResource继承了吗?你定义基类析构函数虚拟?

As rajKumar is pointing out, give us the full code and we'll try to help you.

正如rajKumar指出的那样,给我们完整的代码,我们会尽力帮助你。

#7


0  

I assume CResource is a superclass of some sort for you to allow easy transfer of objects via generalized pointers.

我假设CResource是某种类的超类,允许您通过通用指针轻松传输对象。

Then your question is a normal one for C++ newbies, and you should read

那你的问题对于C ++新手来说是一个正常的问题,你应该阅读

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7

Additionally, get a copy of Scott Meyer's "Effective C++" because it will introduce you to a lot of errors you will be making the next months.

另外,请获取Scott Meyer的“Effective C ++”副本,因为它会向您介绍您将在接下来的几个月内犯下的许多错误。

#1


11  

Summarized possible reasons why CResource destructor may be not called, extracted from other answers:

总结了可能无法调用CResource析构函数的原因,从其他答案中提取:

Incomplete type

One possible cause is you have the CResource type only declared, not defined:

一个可能的原因是您只声明了CResource类型,未定义:

class CResource;

void func(void* data)
{
 CResource* resource = (CResource*)data;
 delete resource; // ~CResource never called.
 resource = NULL;
}

This is an undefined behaviour (deleting incomplete type). In a case like this compiler should issue a warning about destructor not called (Visual C++ definitely does issue it). If this is the case, make sure you have the type defined at the place where you are destructing it (include required headers).

这是一个未定义的行为(删除不完整的类型)。在这样的情况下,编译器应该发出关于未调用析构函数的警告(Visual C ++肯定会发出它)。如果是这种情况,请确保在要销毁它的位置定义了类型(包括所需的标题)。

NULL pointer

If data is NULL, delete does nothing and does not call any destructor.

如果data为NULL,则delete不执行任何操作,也不会调用任何析构函数。

Type mismatch

If CResource destructor is virtual and the object stored on memory pointed to by data is actually a different type, you get an undefined behavior. Often a different destructor will be called (if the object has another virtual destructor), in other situations the program may crash (if the object has no virtual destructor).

如果CResource析构函数是虚拟的,并且存储在数据指向的内存中的对象实际上是不同的类型,则会得到未定义的行为。通常会调用不同的析构函数(如果对象具有另一个虚拟析构函数),在其他情况下程序可能会崩溃(如果对象没有虚拟析构函数)。

#2


6  

The only reason, why the destructor wouldn't be called, is if the data pointer is 0 (or NULL). That's how delete works - it checks if the pointer isn't 0, and if it isn't - it calls the necessary destructors and releases the memory.

导致析构函数不被调用的唯一原因是数据指针是0(或NULL)。这就是删除的工作原理 - 它检查指针是否为0,如果不是,则调用必要的析构函数并释放内存。

As pointed out in the comment. There is another reason why it wouldn't get called. If data points to some other class (not CResource) object and both classes have virtual destructors, then the destructor of that other class will be called.

正如评论中指出的那样。另一个原因是它不会被调用。如果数据指向其他类(而不是CResource)对象,并且两个类都有虚拟析构函数,那么将调用该另一个类的析构函数。

#3


3  

Is the destructor virtual? Maybe data doesn't point to a CResource object at all and the virtual destructor of some other class is being called.

析构函数是虚拟的吗?也许数据根本不指向CResource对象,并且正在调用其他类的虚拟析构函数。

#4


2  

class Aardvark
{
public:
    virtual ~Aardvark()
    {
        printf("Aardvark::~Aardvark\n");
    }
};

class CResource
{
public:
    virtual ~CResource()
    {
        printf("CResource::~CResource\n");
    }
};

void func(void* data)
{
    CResource* resource = (CResource*)data;
    delete resource; // ~CResource never called.
    resource = NULL;
}

int _tmain()
{
    void *data = new Aardvark();
    func( data );
    return 0;
}

#5


0  

Destructor is called.Give us the full code.

调用析构函数。给我们完整的代码。

#6


0  

Why are you saying dtor is not called? Probably because you added a printf in your dtor, and you're not seeing any message?

你为什么说不叫dtor?可能是因为你在你的dtor中添加了printf,而你没有看到任何消息?

Probably another dotr is invoked? Is CResource inherited? Di you define the base class destructor virtual?

可能还会调用另一个dotr? CResource继承了吗?你定义基类析构函数虚拟?

As rajKumar is pointing out, give us the full code and we'll try to help you.

正如rajKumar指出的那样,给我们完整的代码,我们会尽力帮助你。

#7


0  

I assume CResource is a superclass of some sort for you to allow easy transfer of objects via generalized pointers.

我假设CResource是某种类的超类,允许您通过通用指针轻松传输对象。

Then your question is a normal one for C++ newbies, and you should read

那你的问题对于C ++新手来说是一个正常的问题,你应该阅读

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7

Additionally, get a copy of Scott Meyer's "Effective C++" because it will introduce you to a lot of errors you will be making the next months.

另外,请获取Scott Meyer的“Effective C ++”副本,因为它会向您介绍您将在接下来的几个月内犯下的许多错误。