当前位置:  开发笔记 > 编程语言 > 正文

C语言可以决定是否可以访问指针指向的内存?

如何解决《C语言可以决定是否可以访问指针指向的内存?》经验,为你挑选了1个好方法。

例.

如果我有一个指针,

int* p;
p = (int*)2; // just for test
*p = 3; // it will be crack, right?

通常,值2的指针的访问将是破解.但实际上裂缝并非如此简单.指针的无效值可能来自运行时错误.我想在访问之前找到一种检查指针的方法.



1> Basile Stary..:

在标准C99中,这((int*)2 在您的*p =3;语句中解除引用)是未定义的行为(UB).阅读C.Lattner的博客.你应该是很害怕 UB的.这就是为什么在C语言编程如此困难的原因(其他编程语言如Ocaml,Common Lisp的UB要少得多).

AC程序可能有未定义的行为,但可能并不总是崩溃.

在实践中,当用C编码时,要注意指针.明确地(通常是NULL)初始化所有这些.指针算法要非常小心.避免缓冲区溢出和内存泄漏.静态源代码分析可能有所帮助(例如使用Frama-C)但有限(阅读关于暂停问题和赖斯定理).您可以经常使用灵活的数组成员,并在运行时检查指针和索引.

在一些嵌入式独立式C实现中(例如,对类似Arduino的设备进行编码),某些地址可能具有特定含义(例如,某些物理IO设备),因此UB可能非常可怕.

(我在下面关注Linux)

在某些实现和某些操作系统上,您可以测试地址是否有效.例如,在Linux上,您可能会解析/proc/self/maps计算某个给定地址是否有效(有关详细信息,请参阅proc(5)/proc/).

(因此,您可以在Linux上编写一些函数bool isreadableaddress(void*) 来解析/proc/self/maps并判断一个地址在您的进程的虚拟地址空间中是否可读;但由于需要多次系统调用,因此效率不高)

你应该使用valgrind并编译所有警告和调试选项(gcc -Wall -Wextra -g)并使用调试器(gdb)和一些更多的调试编译器选项,如-fsanitize=address

你也许对这处理SIGSEGV 信号,但它是非常棘手和高度不可移植的(操作系统,处理器和ABI特定的).除非你是一个大师,否则你甚至不应该尝试.


请注意,在Windows上有一些功能似乎完全符合OP的要求(IsBadReadPtr等).不要使用它们:https://blogs.msdn.microsoft.com/oldnewthing/20060927-07/?p = 29563 /(标题是"IsBadXXXPtr应该真的称为CrashProgramRandomly").*可能*是一个了解更多的人关于Windows而不是那篇文章的作者,但我不想赌它.每个Windows程序员都应该阅读博客.
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有