【问题标题】:How to safely delete a struct如何安全地删除结构
【发布时间】:2013-11-03 05:49:51
【问题描述】:

我已经定义了这个结构:

typedef struct ethernet_header
{
    UCHAR m_dest[6];
    UCHAR m_source[6];
    USHORT m_type;
}   ETHER_HDR;

然后我在这样的函数中使用它:

void SniffPacket(u_char* p_buffer, int p_size)
{
    //Ethernet header
    ETHER_HDR *l_ethHeader = (ETHER_HDR *)p_uffer;

    //Do Something 
    //How to safely delete l_ethHeader;
}

现在我想在函数离开之前删除l_ethHeader。如何安全地做到这一点。

【问题讨论】:

    标签: c++ pointers memory-management heap-memory


    【解决方案1】:

    你没有!

    你只有deletenew——这里没有new

    【讨论】:

    • 好的,它是从堆中分配的还是从栈中分配的?函数结束时是否释放内存?
    • @ManoubiJonson:我怎么知道这个内存是如何分配的?您还没有显示该代码。您只是在转换一个传递给函数的指针。 p_buffer 指向的内存在函数结束时不会被释放——但这里没有任何迹象表明它应该被释放。
    • 实际上传入的缓冲区可以是堆栈上的一个数组,根本不需要显式删除。事实上,如果它只是用于接收已知长度的标头,它可能应该在堆栈上! :-)
    【解决方案2】:

    视情况而定,

    如果您使用 new 分配了内存,那么您必须使用 deletedelete[](如果是数组),如果您使用 ma​​lloc 函数分配了内存,那么您必须使用 free

    问候

    【讨论】:

      【解决方案3】:

      假设您在输入 SniffPacket 时已经分配了您的 p_buffer,则不要在函数中取消分配它 - 因为您的函数似乎旨在“嗅探”,而不是管理内存。

      如果在您输入 SniffPacket 时未分配它(例如,p_bufferNULL 或未初始化),那么您将在您的演员表中调用未定义的行为,因此您之后所做的任何事情都无关紧要。

      【讨论】:

        【解决方案4】:

        您实际上所做的是告诉编译器将p_buffer 指针值视为指向您的结构的指针,但这样做没有分配额外的内存。正在研究相同的记忆 - 只是有不同的解释。

        如果您希望保留标题,您可以这样做:

        ETHER_HDR l_ethHeader = *(ETHER_HDR *)p_uffer;
        

        它将在堆栈上分配一个头结构,当它超出范围时将自动销毁。

        或者这个:

        ETHER_HDR* l_ethHeader = new ETHER_HDR( *(ETHER_HDR *)p_uffer );
        

        这将在堆上分配一个 需要稍后删除的结构。

        在其他条件相同的情况下,您应该选择选项 1,“始终支持堆栈”。

        【讨论】:

        • 如果 l_ethHeader 被声明在函数之外(一个全局变量)会怎样?
        • 以哪种方式声明?你的?我的一个?虽然坦率地说它并没有太大变化:使用你的方式意味着没有分配额外的内存,因此不需要删除,使用我的第一种方式它将超出范围并在程序关闭时被销毁,所以不需要删除,我的第二种方式您有时需要将其删除以避免内存泄漏。
        【解决方案5】:

        大多数编码风格指南建议分配内存的人也负责释放它。

        你的释放取决于它是如何分配的——你的代码没有分配任何东西,所以我也不希望有任何释放,但是调用你的函数的函数可能需要释放。

        如果它是使用 malloc 分配的——那么你只需释放它。

        如果您的结构是使用“new”分配的,那么您必须使用“delete”并确保您的指针属于同一类型或派生类型(继承),否则解构函数可能无法正确触发。

        在你的情况下,结构是一个普通的旧数据类型,所以不可能说它是使用 malloc、new 还是堆栈变量分配的——后者根本不需要释放作为返回会处理的。

        【讨论】:

        • 请注意,您必须使用与new 相同的delete form。即,如果您使用new[],则必须使用delete[]。如果您使用new,则必须使用delete
        猜你喜欢
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-10
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多