- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经尝试阅读 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()
,但我一直无法理解为什么。此外,在我有权访问的所有编译器( clang
和 gcc
)上,在所有系统(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/
我正在使用一个库 - HtmlUnit - 并且我刚刚从版本 2.4 更新到版本 2.5。当我针对 2.5 编译代码时,我收到一条我不熟悉的奇怪对象“无法取消引用”错误消息。此外,我不明白为什么当我用
我有 C 和 C++ 背景,一直认为 Java 中的解引用是通过对象的引用访问对象的过程。 例如“ref”是一个引用,当用于访问它所引用的Integer对象时,它被解引用: Integer r
这个问题已经有答案了: int cannot be dereferenced (3 个回答) 已关闭 9 年前。 我正在编写一个简单的 Java 程序来进行温度转换,并且在第 8 行(我已在下面的代码
请在说明中包含一个示例。 最佳答案 回顾基本术语 通常情况下就足够了 - 除非您正在编写程序集 - 设想一个 指针包含一个数字内存地址,其中 1 表示进程内存中的第二个字节,2 表示第三个字节,3 表
本题将从草稿N1570中获取信息,所以基本上是C11。 通俗地说,取消引用指针意味着将一元 * 运算符应用于指针。草稿文件中只有一处存在“取消引用”一词(没有“取消引用”的实例),并且位于脚注中: 1
我有这三个文件。使用结构体、函数和指针。 尝试这样做: void getName(Name *) - 接收指向名称的指针并执行操作 联系人.h struct Name { char firstNam
好的,所以我需要生成 7 个 1 到 100 之间的随机数,并将最大值打印在屏幕上。但是,当我编译此代码时: public class ArrayofTemperatures { public
我喜欢代码让我头疼的时候。除了这个。我只是使用一种常用的算法用随机 double 填充一个 vector 。问题是,在编译之后,它给了我一个“Iterator not dereferenceable”
我有 C 和 C++ 背景,一直认为 Java 中的解引用是通过对象的引用访问对象的过程。 例如“ref”是一个引用,当用于访问它所引用的Integer对象时,它被解引用: Integer r
本题将从草稿中抽取信息N1570 ,所以 C11 基本上。 通俗地说,取消引用指针意味着将一元 * 运算符应用于指针。文档草案中只有一个地方存在“取消引用”一词(没有“取消引用”的实例),并且在脚注中
我正在尝试实现一个提供 map 标记动画的库,但是当我尝试添加一些高级方法时,它在第二个“.withFillColor(Color.BLUE)”上抛出一个错误,其中显示:错误: void 无法取消引用
我收到以下代码的“int 无法取消引用”错误。任何帮助表示赞赏。谢谢: public int value() { int total = 0; **for (int i = 0; i < wallet
编译时我似乎收到“错误:int 无法取消引用”错误。我已经查找了发生这种情况的原因,尽管如此,我不确定如何解决它。 public class NetID_BaseballPitcher { S
这是我遇到问题的地方。 double num1 = Math.random(); double num2 = Math.random(); if (num1 < num2.nu
所以,我花了一些时间编写一些计算方法,以便在我正在尝试制作的角色扮演游戏的预览战斗窗口中获取一些导入数字(有人还记得《火焰纹章》吗?这是它的简化版本)。这是我尝试从这些 c 形成 jtable 的地方
我问的问题非常基础,但我试图通过在编译器中做练习来理解 C++ 中指针的行为。因此,例如,我首先声明一个 int 指针 *p 并尝试为其赋予一些值并打印它: #include using names
这里我有一些值,其中两个是整数,我不能对它们调用方法,因为它们不是引用。我该如何解决这个问题? String srcAddr, dstAddr, protocol; int srcPort, dstP
我有以下代码部分,它给出了明确的 null 取消引用。 uint64_t *var1 = NULL; char *var2 = NULL; //Alias transfer var1 = (uint6
在 C 中,是否可以为取消引用的指针定义别名/快捷方式? 即假设定义如下: void * ptr_to_my_variable = 0x2ff00000; 是否可以定义一个对应于 *ptr_to_my
假设我有这样的东西: class Collection { private: typedef std::vector >::iterator Iterator; std::vector
我是一名优秀的程序员,十分优秀!