繁体   English   中英

指向空函数的参数的指针

[英]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函数的众多调用之一:

FREE(Buffer);

在此示例中,“缓冲区”是指向未签名字符的指针。

unsigned char *Buffer;

出于参考目的,对于此特定示例,我收到的错误是“无法将参数1从'unsigned char *'转换为'void **'”

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

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

这个错误的原因进行了说明这里 ,由昆汀如指出。

您可以选择的替代代码是:

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

我在运行代码变体时遇到的问题是VirualFree和VirtualAlloc的用法不一致,即在您提供的代码示例中,我看不到VirtualAlloc()用法的指示,应将其与VirtualFree()结合使用。

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

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

从此处改编 :(此程序构建并运行无错误,演示了与VirtualFree()结合使用的VirtualAlloc()用法)

#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;
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM