簡體   English   中英

如何在C ++ DLL中釋放已分配的內存

[英]How to free allocated memory in C++ DLL

我有以下代碼來加密C ++ DLL中的字符串

EXPORT WCHAR* EncryptString(WCHAR* stringToEncrypt) {
    aes_context ctx;

    WCHAR* in = stringToEncrypt;
    WCHAR* out;
    WCHAR* key = L"TestKey";

    BYTE* buffEnc = (BYTE*)malloc(16);
    BYTE* keyBuffEnc = (BYTE*)malloc(32);

    memset(buffEnc, 0, 16);
    memset(keyBuffEnc, 0, 32);

    memcpy(buffEnc, in, wcslen(in) * 2);
    memcpy(keyBuffEnc, key, wcslen(key) * 2);
    aes_set_key(&ctx, keyBuffEnc, 256);

    aes_encrypt(&ctx, buffEnc, buffEnc);
    out = (WCHAR*)buffEnc;

    // free(buffEnc);   
    // free(keyBuffEnc);

    return out;
}

我的問題是我無法釋放分配的內存,否則結果會被破壞。 我想知道如何在不丟失結果的情況下釋放使用過的內存? 我要改變返回值的類型嗎?

在此先感謝您的幫助。 迎接亨氏

這確實是一個有問題的情況 - 你返回一個指向已分配內存的指針,並且不清楚誰應該釋放內存。 您有以下選擇:

  1. 告訴調用者使用free()釋放內存 - 這只有在他們使用難以保證的相同堆時才會起作用。 這是非常不可靠的,並不是真的推薦。
  2. 引入一個內存管理接口(例如你的庫中實現的freeEncrypted()函數)並告訴調用者使用它 - 然后內存將返回到正確的堆。
  3. 使用像CoTaskMemAlloc()這樣眾所周知的東西進行分配,並告訴調用者使用匹配函數(如CoTaskMemFree()來釋放內存。 這類似於第2點,只使用一個眾所周知的通用內存管理器。
  4. 更改接口,使其接受指向已分配數據及其大小的指針,以便調用者分配和釋放內存。

在Windows上,內存管理器(其中包括跟蹤進程中分配的和可用內存)在C運行時庫中工作。 這意味着如果你有兩個模塊(比如:你的實際可執行文件和一個DLL,或兩個DLL),你想讓一個模塊分配一些內存而另一個模塊應該擁有它(即負責釋放它或傳遞它維護人員基本上有三種選擇:

  1. 您讓調用者分配一塊內存並將指針傳遞給被調用者。 在您的示例中,這將歸結為調用者分配一個(希望足夠大)緩沖區,然后將指針傳遞給EncryptString函數。 這種方法的優點是調用者可以選擇在堆棧上分配一塊內存,然后將指針傳遞給它,類似於

     WCHAR buf[1024]; EncryptString( "Hello", buf ); // Won't compile, "Hello" is a const string 

    缺點是調用者必須首先找出合適的緩沖區大小。 您可以強加一個最大限制並記錄該文件,或者您可以使用公開的專用函數來計算所需的大小,或者您可以說如果將NULL作為輸出緩沖區傳遞,則該函數返回所需字符的數量。 后者通常由Windows API使用。

  2. 你讓被調用者使用例如mallocnew來分配內存(正如你的函數所做的那樣)但是然后要求調用者必須使用特殊函數再次釋放內存,比如FreeEncryptedString(char *s) 這個想法是你的DLL也暴露了這個釋放函數,它只是調用適當的釋放函數(即freedeletedelete[]等),這樣分配和釋放都發生在同一個模塊中。

  3. 您確保兩個模塊動態鏈接到同一個C運行時庫,即在此過程中只有一個C運行時DLL副本,並且兩個模塊都使用它。 在這種情況下,您可以根據需要使用mallocfree (或newdelete等)。 這樣做的好處在於它非常簡單,缺點是它意味着你對模塊的構建方式提出了要求(如果你在加載由其他人編寫的插件的程序上工作,這可能是不可能的 - 這些插件可能選擇靜態鏈接C運行時)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM