C 如何使用内置函数而不是空检查来验证指针?
在今天的一次讨论中,我发现在VxWorks和LynxOS中有一些检查,它们告诉您为指针指定的地址来自有效范围。这是我第一次听到这个代码,就像我赋值C 如何使用内置函数而不是空检查来验证指针?,c,linux,memory,vxworks,lynxos,C,Linux,Memory,Vxworks,Lynxos,在今天的一次讨论中,我发现在VxWorks和LynxOS中有一些检查,它们告诉您为指针指定的地址来自有效范围。这是我第一次听到这个代码,就像我赋值int*I=&variable 我应该得到一个警告或错误,在我的应用程序中,我不能将地址值分配给整数 当我执行空检查时,我只检查地址0x00000000。但也可能存在这样的情况:地址可能是0x00000001。如果它是一个未映射的区域并且可能无法访问,那么它也是无效的。是否有人知道Linux有类似的功能,或者可以指导如何在VxWorks或LynxOS中
int*I=&variable代码>
我应该得到一个警告或错误,在我的应用程序中,我不能将地址值分配给整数
当我执行空检查时,我只检查地址0x00000000
。但也可能存在这样的情况:地址可能是0x00000001
。如果它是一个未映射的区域并且可能无法访问,那么它也是无效的。是否有人知道Linux有类似的功能,或者可以指导如何在VxWorks或LynxOS中完成这些功能
有什么想法吗 这里有几个误解:
- 从C语言的角度来看,只有一个指针值被保证为无效,这就是
NULL
。对于其他值,它取决于上下文。指针指向当前处于活动状态的对象时有效。(请注意,在您的int*i=&variable
示例中,这是非常正确的,因为只有当有一个variable
可从当前范围访问时,这才是有效的语法)
NULL
不一定意味着所有位都为零的值。这是最常见的情况,但也有一些平台对NULL
指针使用不同的位模式。C标准甚至允许不同类型的指针对NULL
有不同的表示。不过,将0
转换为指针类型肯定会导致此类型的NULL
指针
- 我不知道你在VxWorks中到底指的是什么,但Linux当然会检查内存访问。如果进程试图访问虚拟地址空间中未映射的地址,则会向该进程发送一个
SIGSEGV
信号,这会立即导致程序异常终止(分段故障)
如中所述,通常情况下,您不能做自己想做的事情
我应该得到一个警告或错误,在我的应用程序中,我不能将地址值分配给整数
静态且可靠地检测所有指针故障是不可能的(因为可以证明这等同于解决问题)。顺便说一下,你可以考虑使用像./p>这样的工具。
在Linux上,原则上,您可以在运行时测试给定地址在您的计算机中是否有效,例如使用/proc/
,例如通过解析/proc/self/maps
伪文本文件(要理解我的意思,请在终端中尝试cat/proc/$$$/maps
,然后cat/proc/self/maps
)。看见在实践中,我不建议经常这样做(可能太慢),当然这不是编译器的功能(您应该自己编写)。顺便说一句,请注意
但是,有一些工具可以帮助检测(某些)错误的地址使用,特别是该功能,请阅读GCC的相关内容,并尝试使用-fsanize=address
进行编译
不要忘记用所有警告和调试信息编译代码,所以使用gcc-Wall-Wextra-g
编译它
顺便说一句,如果您将某个局部变量的地址存储在某个全局指针中,并在该局部变量在作用域中之后取消引用该指针,那么您仍然会有一些(即使您的代码没有崩溃,因为您通常会取消对某个随机地址的引用),并且您应该非常谨慎。应始终避免UB。您在VxWorks中寻找的函数称为vxMemProbe
基本上,vxMemProbe库插入特殊的异常处理代码来捕获页面错误或总线错误。vxMemProbe功能用于检查地址是否可用于读取或写入。它还允许您测试特定地址是否可以通过给定的数据宽度(8,16,32,64位)和对齐方式访问
vxMemProbe的底层机制与特定的体系结构异常处理机制相关联。vxMemProbe库将代码插入异常处理程序。当您探测触发异常的地址时,处理程序会检查vxMemProbe是否触发了异常。如果是这样,那么处理程序将在异常发生之前恢复状态处理器,并将执行返回到调用vxMemProbe的位置,同时还通过给定的调用约定返回值 我想您可以尝试mlock
,如果它不是映射内存,它将返回一个错误…@Antti Haapalaint*I=&variable
将始终be@PeterJ_01又错了。NULL
指针在布尔上下文中的计算结果为false,无论其表示形式是什么。@PeterJ_01:否编译器可以针对这种情况发出特殊测试。@Felix Palmen值为0的整型常量表达式,或转换为void*类型的表达式,被称为空指针常量。66)
@Felix Palmen只是快速查看了一下。该行为在标准中的何处描述<代码>又错了。在布尔上下文中,空指针的计算结果为false,而不管它在引用的部分中的表示形式是什么
@PeterJ_01。强制转换是一种显式转换,对于这个空指针的表示形式没有任何说明。一个表达式和一个表示法是完全不同的。为什么这个答案会被接受?问题是在Linux上做类似的事情@除了,如果你读了这个问题,最后是。。。或者可以指导如何在VxWorks或LynxOS上完成