指向 Void 函数参数的指针

Pointer to Pointer to Void Function Parameter

我有一个我正在修改的驱动程序,它是由其他人用 C 语言编写的。由于我需要添加一些 C++ 函数调用,我现在正在使用 C++ 编译器与 C 编译器构建驱动程序(在 Visual Studio 2012)。当我改用 C++ 时,我收到了很多构建错误,除了少数之外,所有这些我都能够修复。少数错误都与对同一函数的调用有关。我在网上广泛搜索以尝试找到解决此问题的方法,但没有成功。下面是这个问题的组成部分,我希望有人能帮助我解决这个问题。

首先,这是被调用的函数。您可能想知道为什么最初的 S/W 开发人员创建了他们自己的自定义空闲内存函数,而他们本可以使用标准 C 库中的 free() 函数。我不知道这是为什么,但因为它工作得很好,我犹豫要不要改变它。

void freeMemory(void **pBuffer)
{
    BOOL result;
    ASSERT(pBuffer != NULL);

    // see if buffer is already been freed
    if (*pBuffer == NULL)
    {   
        return;
    }

    result = VirtualFree(
        *pBuffer,                   // LPVOID lpAddress,   // address of memory
        0,                          // SIZE_T dwSize,      // size of memory
        MEM_RELEASE                 // DWORD dwFreeType    // operation type
        );
    // see of we were able to successfully free the memory  
    if (result == FALSE)
    {   
        ASSERT(FALSE);
        return;
    }

    // Mark the buffer pointer as now being free
    *pBuffer = NULL;
}  

所以这个拼图的下一个部分是#define 如下:

#define FREE(pBuffer) freeMemory(&(pBuffer))

最后,下面是对这个免费函数的许多调用之一:

FREE(Buffer);

在这个例子中,"Buffer" 是一个指向无符号字符的指针。

unsigned char *Buffer;

出于参考目的,对于这个特定示例,我收到的错误是 "cannot convert parameter 1 from 'unsigned char *' to 'void **'"

我已经很长时间没有直接使用 C 或 C++ 做过很多事情了,指针从来都不是我的强项。基于错误,我的假设是此错误与未在函数调用中提供强制转换有关,但考虑到如何从标准 C 库中使用 free() 函数,似乎没有必要这样做。任何关于如何调用 FREE 函数来消除这些错误的帮助,我将不胜感激。

freeMemory 用于创建一个安全的自由,因为您可以为同一个指针调用它两次而不会造成任何伤害。我不喜欢这样,它只会隐藏你的错误,但在周围很常见。

根据 Quentin 的指示,here 解释了此错误的原因。

您的替代代码是:

#define FREE(pBuffer) \
{ \
    void *tmp; \
    tmp = pBuffer; \
    freeMemory(&tmp); \
    pBuffer = tmp; \
}

当您的代码 运行 变体时,我遇到的问题是 VirualFree 和 VirtualAlloc 的使用不一致,即在您提供的代码示例中,我看不到 VirtualAlloc() 用法的迹象,这应该与 VirtualFree().

结合使用

另外,当我尝试使用VirtualAlloc()将内存分配给特定地址时,它总是失败,所以我让系统指定地址。下面是演示分配和释放页面内存的代码片段。

编辑 这现在解决了您的宏问题,它使用了 Jonaton 的宏定义建议(带有两个额外的 ;)。

Adapted from here:(这个构建和运行没有错误,演示了[=11=的用法] 与 VirtualFree())

结合使用
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>             

#define PAGES 100            

LPTSTR lpNxtPage;               
DWORD dwPages = 0;              
DWORD dwPageSize;

void freeMemory(void **pBuffer);

#define FREE(pBuffer) \
{ \
    void *tmp; \
    tmp = pBuffer; \
    freeMemory(&tmp); \
    pBuffer = tmp; \
}

void main(void)
{
    LPVOID lpvBase;               
    LPTSTR lpPtr;                 
    BOOL bSuccess;                
    DWORD i;                      
    SYSTEM_INFO sSysInfo;         

    GetSystemInfo(&sSysInfo);     


    dwPageSize = sSysInfo.dwPageSize;


    lpvBase = VirtualAlloc(
                     NULL,                 
                     PAGES*dwPageSize, 
                     MEM_RESERVE,          
                     PAGE_NOACCESS);       
    if (lpvBase == NULL )//do nothing

    lpPtr = lpNxtPage = (LPTSTR) lpvBase;


   // bSuccess = VirtualFree(
   //                    lpvBase,       
   //                    0,             
   //                    MEM_RELEASE); 
    FREE(lpvBase)  //replace in-line VirtualFree with macro

    ;
}


void freeMemory(void **pBuffer)
{
    BOOL result;
    assert(pBuffer != NULL);

    // see if buffer is already been freed
    if (*pBuffer == NULL)
    {   
        return;
    }

    result = VirtualFree(
        *pBuffer,                   // LPVOID lpAddress,   // address of memory
        0,                          // SIZE_T dwSize,      // size of memory
        MEM_RELEASE                 // DWORD dwFreeType    // operation type
        );
    // see of we were able to successfully free the memory  
    if (result == FALSE)
    {   
        assert(FALSE);
        return;
    }

    // Mark the buffer pointer as now being free
    *pBuffer = NULL;
}