C++重載delete的隱患

大家好,今天小編帶大家了解重載deletec操作符中的隱患。重載delete卻有隱患,到底是怎么一回事呢?讓我們一起來(lái)看看吧。
出于一些特殊的業(yè)務(wù)需要(比如統(tǒng)計(jì)程序的內(nèi)存使用狀況),我們可能會(huì)對(duì)new和delete操作符進(jìn)行重載。如果此時(shí)在工程中使用了外部鏈接庫(kù),并且在使用外部類時(shí)包含頭文件不夠嚴(yán)謹(jǐn),將會(huì)導(dǎo)致析構(gòu)階段出現(xiàn)外部類的析構(gòu)函數(shù)無(wú)法被正確執(zhí)行的情況。
我們做以下實(shí)驗(yàn)(開(kāi)發(fā)環(huán)境vs2017)
鏈接庫(kù)中定義的類:
頭文件mylib.h

#pragma once
class MyLib
{
public:
    int* m_p;
    MyLib();
    ~MyLib();
};

cpp文件mylib.cpp
注意我們?cè)谖鰳?gòu)函數(shù)中加了一條打印,來(lái)輔助判斷是否正確執(zhí)行了析構(gòu)

#include <iostream>
#include "mylib.h"
MyLib::MyLib()
{
    m_p = new int;
    *m_p = 1;
}

MyLib::~MyLib()
{
    std::cout << "MyLib Destructor" << std::endl;
    if (m_p)
    {
        delete m_p;
        m_p = nullptr;
    }
}

本地工程中的類test.h,包含了一個(gè)外部類指針,但在類定義中只做聲明沒(méi)有使用

#pragma once
class MyLib;
class LocalTest
{
public:
    MyLib* m_lib;
    LocalTest();
    ~LocalTest();
};

LocalTest類的構(gòu)造和析構(gòu)函數(shù)在test.cpp中
注意這里我們沒(méi)有包含外部類的頭文件mylib.h

#include "test.h"

LocalTest::LocalTest()
{
    m_lib = nullptr;
}

LocalTest::~LocalTest()
{
    if (m_lib)
    {
        delete m_lib;
        m_lib = nullptr;
    }
}

在另一個(gè)cpp文件中創(chuàng)建一個(gè)LocalTest對(duì)象,并給MyLib指針賦值,最后析構(gòu)LocalTest對(duì)象

#include <iostream>
#include "mylib.h"
#include "test.h"

//重載delete運(yùn)算符
void operator delete(void* p)
{
    //do something...
    free(p);
}

int main()
{
    LocalTest* test = new LocalTest;
    test->m_lib = new MyLib;//在這里給MyLib指針賦值
    delete test;
    system("pause");
    return 0;
}

我們看一下運(yùn)行結(jié)果


image.png

可以看到外部類的析構(gòu)函數(shù)并沒(méi)有被執(zhí)行
我們反匯編證實(shí)一下

image.png
image.png

編譯器在執(zhí)行MyLib析構(gòu)時(shí)執(zhí)行的時(shí)我們重載的delete而非~MyLib()
現(xiàn)在我們做一點(diǎn)修改,在本地類test.cpp文件中包含外部類的頭文件,重新編譯運(yùn)行
image.png

image.png

可以看到外部類的析構(gòu)函數(shù)被正確執(zhí)行了。
再次查看匯編代碼,可以發(fā)現(xiàn)此時(shí)編譯器已經(jīng)找到了正確的析構(gòu)函數(shù)


image.png

而如果你將本地類的析構(gòu)函數(shù)的實(shí)現(xiàn)放在了頭文件中而非cpp中,幸運(yùn)的是這樣編譯器也能找到正確的找到析構(gòu)函數(shù)(~ ̄ ̄)~。
這就是重載delete時(shí)的隱患了,不知道大家有什么想法呢?歡迎在屏幕下方留言哦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容