C 如何使用内置函数而不是空检查来验证指针?

C 如何使用内置函数而不是空检查来验证指针?,c,linux,memory,vxworks,lynxos,C,Linux,Memory,Vxworks,Lynxos,在今天的一次讨论中,我发现在VxWorks和LynxOS中有一些检查,它们告诉您为指针指定的地址来自有效范围。这是我第一次听到这个代码,就像我赋值int*I=&variable 我应该得到一个警告或错误,在我的应用程序中,我不能将地址值分配给整数 当我执行空检查时,我只检查地址0x00000000。但也可能存在这样的情况:地址可能是0x00000001。如果它是一个未映射的区域并且可能无法访问,那么它也是无效的。是否有人知道Linux有类似的功能,或者可以指导如何在VxWorks或LynxOS中

在今天的一次讨论中,我发现在VxWorksLynxOS中有一些检查,它们告诉您为指针指定的地址来自有效范围。这是我第一次听到这个代码,就像我赋值
int*I=&variable

我应该得到一个警告或错误,在我的应用程序中,我不能将地址值分配给整数

当我执行空检查时,我只检查地址
0x00000000
。但也可能存在这样的情况:地址可能是
0x00000001
。如果它是一个未映射的区域并且可能无法访问,那么它也是无效的。是否有人知道Linux有类似的功能,或者可以指导如何在VxWorksLynxOS中完成这些功能


有什么想法吗

这里有几个误解:

  • 从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 Haapala
int*I=&variable
将始终be@PeterJ_01又错了。
NULL
指针在布尔上下文中的计算结果为false,无论其表示形式是什么。@PeterJ_01:否编译器可以针对这种情况发出特殊测试。@Felix Palmen
值为0的整型常量表达式,或转换为void*类型的表达式,被称为空指针常量。66)
@Felix Palmen只是快速查看了一下。该行为在标准中的何处描述<代码>又错了。在布尔上下文中,空指针的计算结果为false,而不管它在引用的部分中的表示形式是什么
@PeterJ_01。强制转换是一种显式转换,对于这个空指针的表示形式没有任何说明。一个表达式和一个表示法是完全不同的。为什么这个答案会被接受?问题是在Linux上做类似的事情@除了,如果你读了这个问题,最后是。。。或者可以指导如何在VxWorks或LynxOS上完成