当前位置: 首页 > 知识库问答 >
问题:

指向包含std::字符串的对象的指针上调用析构函数的指针无效

王杰
2023-03-14

我使用的是BennyBox频道上的ECS的一个修改版本(代码可以在这里找到),它在大多数情况下都能正常工作。但是,当我向组件添加std::string时,程序在退出时中止(当ECS类的析构函数被调用时),并显示消息:free():指针无效。当我从组件中删除字符串时,程序将毫无问题地退出。所有组件都继承自此类:

template<typename T>
struct ECSComponent : public BaseECSComponent
{
    static const ECSComponentCreateFunction CREATE_FUNCTION;
    static const ECSComponentFreeFunction FREE_FUNCTION;
    static const uint32 ID;
    static const size_t SIZE;
};

它继承自一个类,该类只包含一个指向向量的指针和几个辅助函数。组件被破坏如下:

template<typename Component>
void ECSComponentFree(BaseECSComponent* comp)
{
    Component* component = (Component*)comp;
    component->~Component();
}

该程序使用const char*代替字符串,但我不能这样做,因为我需要这个特定的字符串是动态的。它还适用于其他常见的数据结构,例如std::向量...这里发生了什么?


共有1个答案

微生嘉
2023-03-14

您的问题出在ECSComponentFree()函数中,您手动调用析构函数:

template<typename Component>
void ECSComponentFree(BaseECSComponent* comp)
{
    Component* component = (Component*)comp;
    component->~Component(); //call the destructor
}

当对象超出范围时,会再次调用析构函数,它试图再次释放内存,导致双重释放。

您可以通过运行以下简单示例尝试直播来更好地理解它:

class A {
    std::string* s = new std::string{"Hello"};
    public:
    A() { printf("ctor\n"); }
    void freee() { printf("freeing\n"); this->~A(); }
    ~A() { delete s; printf("dtor\n"); }
};

int main()
{
    A a;
    a.freee();
    return 0;
}
 类似资料:
  • 主要内容:到底使用字符数组还是字符串常量C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这在《 C语言字符数组和字符串》中已经进行了详细讲解,这里不妨再来演示一下: 运行结果: https://www.xnip.cn https://www.xnip.cn 字符数组归根结底还是一个数组,上节讲到的关于 指针和数组的规则同样也适用于字符数组。更改上面的代码,使用指针的方式来输出字符串: 运行结果: https://ww

  • 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType

  • 指针概述 指针的概念 在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,例如int型占4个内存单元,char型占1个内存单元。为了正确地访问这些内存单元,必须为每个内存单元编上号,根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = &pi; 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • 问题内容: 有没有机会从以字符串表示的函数名称中获取指向函数的指针?例如,这需要将某些函数作为参数发送给另一个函数。您知道某种元编程。 问题答案: Go函数是一等值。您无需恢复动态语言中的技巧。 操场 输出: 如果函数的选择取决于某些仅在运行时已知的值,则可以使用映射: