gpt4 book ai didi

调用一个 free() 包装器 : dereferencing type-punned pointer will break strict-aliasing rules

转载 作者:太空狗 更新时间:2023-10-29 14:51:10 26 4
gpt4 key购买 nike

我已经尝试阅读 SO 上具有类似标题的其他问题,但它们都太复杂了,我无法将解决方案(甚至解释)应用于我自己的问题,似乎具有更简单的性质。

在我的例子中,我有一个围绕 free() 的包装器它将指针设置为 NULL释放后:

void myfree(void **ptr)
{
free(*ptr);
*ptr = NULL;
}

在我正在做的项目中,它是这样调用的:

myfree((void **)&a);

这使得 gcc (OpenBSD 上的 4.2.1)如果我将优化级别提高到 -O3 会发出警告“取消引用类型双关指针将打破严格的别名规则”并添加 -Wall (不是别的)。

调用 myfree()以下方式不会使编译器发出该警告:

myfree((void *)&a);

所以我想知道我们是否应该改变我们调用 myfree() 的方式对此。

我相信我正在使用第一种调用方式调用未定义的行为 myfree() ,但我一直无法理解为什么。此外,在我有权访问的所有编译器( clanggcc )上,在所有系统(OpenBSD、Mac OS X 和 Linux)上,这是唯一实际给我警告的编译器和系统(我知道发出警告是一个不错的选择)。

在调用 myfree() 之前、内部和之后打印指针的值,通过两种调用方式,给出了相同的结果(但如果它是未定义的行为,那可能没有任何意义):

#include <stdio.h>
#include <stdlib.h>

void myfree(void **ptr)
{
printf("(in myfree) ptr = %p\n", *ptr);
free(*ptr);
*ptr = NULL;
}

int main(void)
{
int *a, *b;

a = malloc(100 * sizeof *a);
b = malloc(100 * sizeof *b);

printf("(before myfree) a = %p\n", (void *)a);
printf("(before myfree) b = %p\n", (void *)b);

myfree((void **)&a); /* line 21 */
myfree((void *)&b);

printf("(after myfree) a = %p\n", (void *)a);
printf("(after myfree) b = %p\n", (void *)b);

return EXIT_SUCCESS;
}

编译运行:

$ cc -O3 -Wall free-test.c
free-test.c: In function 'main':
free-test.c:21: warning: dereferencing type-punned pointer will break strict-aliasing rules

$ ./a.out
(before myfree) a = 0x15f8fcf1d600
(before myfree) b = 0x15f876b27200
(in myfree) ptr = 0x15f8fcf1d600
(in myfree) ptr = 0x15f876b27200
(after myfree) a = 0x0
(after myfree) b = 0x0

我想了解第一次调用 myfree() 有什么问题我想知道第二个电话是否正确。谢谢。

最佳答案

因为a是一个int*而不是一个void*&a不能被转换成一个指针到 void*。 (假设 void* 比指向整数的指针更宽,这是 C 标准允许的。)因此,您的两个替代方案 -- myfree((void**)a) myfree((void*)a) - 是正确的。 (转换为 void* 不是严格的别名问题。但它仍然会导致未定义的行为。)

更好的解决方案(恕我直言)是强制用户插入可见分配:

void* myfree(void* p) {
free(p);
return 0;
}

a = myfree(a);

用clang和gcc,可以用一个属性来指明必须使用my_free的返回值,这样如果忘记赋值,编译器就会警告你。或者您可以使用宏:

#define myfree(a) (a = myfree(a))

关于调用一个 free() 包装器 : dereferencing type-punned pointer will break strict-aliasing rules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38569628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com