[英]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.