c - 将 char** 传递给 void** 函数参数时,与指针类型不兼容的指针类型警告
问题描述
我正在尝试实现一个安全释放函数,该函数擦除分配的内存,释放它,然后还将指向分配区域的指针设置为 NULL,因此指针不能在释放后重用,也不能使用相同的函数进行双重释放. 为了实现这一点,我使用了一个指向指针的参数,它允许我覆盖指向已分配内存的指针。
问题是 GCC 抱怨指针类型不兼容(“但它在我的机器上工作”);我没想到会有这样的警告。我的理解是任何指针都可以隐式转换为void*
,因此我猜测指针的地址也可以转换为void**
.
同时我重写secure_free()
为一个宏,它解决了警告,但我想知道编译器为什么抱怨。
文件securefree.c
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define STRING_BUFFER_LEN 10
/**
* Securely erases a heap-allocated memory section, frees it and sets its
* pointer to NULL to avoid use-after-free and double-free.
*/
static void secure_free(void** p_p_data, size_t length_in_bytes)
{
if (p_p_data == NULL || *p_p_data == NULL)
{ return; }
memset(*p_p_data, 0, length_in_bytes);
free(*p_p_data);
*p_p_data = NULL;
}
int main(void)
{
// Allocate some data
char* my_string = calloc(STRING_BUFFER_LEN, sizeof(char));
if (my_string == NULL) { return 1; }
// Use the allocated space in some way
my_string[0] = 'a';
my_string[1] = 'b';
// Free using the dedicated function
secure_free(&my_string, STRING_BUFFER_LEN);
return 0;
}
使用 GCC 编译(Rev6,由 MSYS2 项目构建,10.2.0):
$ gcc securefree.c -o securefree
securefree.c: In function 'main':
securefree.c:29:17: warning: passing argument 1 of 'secure_free' from incompatible pointer type [-Wincompatible-pointer-types]
29 | secure_free(&my_string, STRING_BUFFER_LEN);
| ^~~~~~~~~~
| |
| char **
securefree.c:11:32: note: expected 'void **' but argument is of type 'char **'
11 | static void secure_free(void** p_p_data, size_t length_in_bytes)
| ~~~~~~~^~~~~~~~
编辑:宏版本看起来像这样
#define secure_free_macro(ptr, len) if ((ptr) != NULL) { \
memset((ptr), 0, (len)); free(ptr); (ptr) = NULL; }
解决方案
您尝试做的事情不能移植,因为不同的指针类型可以有不同的表示;并且要将空指针分配给该值,您必须首先将指针指针转换为指向实际指针变量的有效类型的指针 - 这是不可能的。
但是,您可以做的是使用宏,它与任何宏一样好,并且使用起来更简单:
#define secure_free(x) (free(x), (x) = 0)
这在没有&
.
推荐阅读
- javascript - 理解 CSS 代码片段在 ReactApp 中实现视差效果
- java - Java Swing 标签未出现
- r - 尝试使用 rnorm 函数模拟数据集时遇到语法错误
- android - 视图绑定无权访问片段
- linux - 我在使用 bochs+gdb 调试 linux-0.11 时遇到了一些问题
- bash - Terraform GCP 实例元数据启动脚本问题
- python-3.x - 无法在 leetcode 每周竞赛 243 中提出的“使用服务器处理任务”问题中找到边缘案例
- python - 错误:“NoneType”和“int”的实例之间不支持“>”
- amazon-web-services - 为什么我的 AWS S3 对象计数不同
- python-3.x - 有没有办法使用python从文本文件中只提取特定的行