【问题标题】:NULL function pointers空函数指针
【发布时间】:2013-02-11 22:47:57
【问题描述】:

调用空函数指针的行为是什么?

void (*pFunc)(void) = NULL;  
pFunc();

为什么建议将尚未使用的函数指针初始化为 NULL?

【问题讨论】:

标签: c++ c c99


【解决方案1】:

出于与初始化指向NULL 的“正常”(数据)指针相同的原因,建议这样做:因为它可能会使一些错误更容易追踪。关于这是否有用的意见当然会有所不同:-)

【讨论】:

    【解决方案2】:

    在 C 和 C++ 中,这称为 undefined behaviour,这意味着这可能会导致 分段错误,根据您的编译器、您的操作系统,不会或任何此类情况导致重新运行这段代码,环境(等等)意味着。

    初始化指向函数的指针,或一般指向 NULL 的指针有助于一些开发人员确保其指针未初始化且不等于随机值,从而防止他们意外取消引用。

    【讨论】:

    • 这将导致 99% 的情况和许多系统/架构出现分段错误。但是,该标准并未明确说明它会发生。
    • 我认为这是“未指定”的行为,但并非真正未定义。如果内存 0x0 是可寻址和“可执行的”...
    • @rodrigo:对。我想知道的是标准是否明确规定不允许将 0x0 作为有效的内存地址。那么它将是“未定义的行为”。如果它不这么说,那么它就是未指定的——它们本质上是两个不同的东西。
    • @VladLazarenko:标准没有说明地址 0x0。关于NULL 指针,它只说了两件事:没有有效的函数对象具有地址NULL;并且引用/调用NULL 指针是UB。现在,实现可以选择记录该特定行为,甚至可以指定NULL 指针的二进制值。有关更好的解释,请参阅this other question
    • @vonbrand:你是对的:文字0 可以用作NULL 指针常量。但这并不意味着 NULL 指针位于地址 0x0 或它是全零位模式。 NULL 指针的实际地址是实现定义的。令人困惑,我知道,但就是这样。
    【解决方案3】:
    1. 当你尝试访问 NULL 时会发生什么? 以下关于数据和代码都是正确的,这就是 当您尝试读取 NULL(或从 0 到 4096,即段的至少第一页)。造成这种情况的根本原因在于 操作系统和微处理器分段/分页架构

      当您尝试在任何数据或代码中访问 NULL(或 0)地址时 部分,它会导致分段错误(这实际上是一个杀手 页面错误)。部分的第一页被视为超出(或无效 部分)虚拟地址空间。那是故意的第一页 保持无效(或不存在),因此至少有一个地址该指针 包含可能在执行时在程序中表示为无效 时间。

      第 1 页的页描述符(包含虚拟地址 0, NULL),第一位“存在”为 0(表示其无效页面)。现在如果 您尝试访问 NULL 指针(0 地址),这将导致引发 页面错误,因为页面不存在,操作系统将尝试处理此问题 页面错误。当页面错误处理程序看到它试图访问时 第 1 页,被视为虚拟地址的无效部分 空间它会杀死进程。这都是关于用户空间进程的。如果 您尝试在系统进程(内核级代码)中访问 NULL 指针, 它将使您的操作系统失败并导致系统崩溃。

      链接:http://en.wikipedia.org/wiki/Page_fault#Invalid http://en.wikipedia.org/wiki/Memory_protection#Paged_virtual_memory http://pdos.csail.mit.edu/6.828/2005/readings/i386/s05_02.htm

      以上内容就足够了,因为我认为您也应该阅读此内容 http://www.iecc.com/linker/linker04.txt

    2. 为什么函数指针被初始化为NULL? 尽管如果您尝试使用 NULL 调用它,则会出现页面/段错误。 NULL 表示它的无效功能。如果它 包含任何垃圾地址,但在有效的虚拟地址空间中 代码部分,我认为该地址的任何代码都会被调用, 可能是更大的灾难(在实时系统的情况下是 spl)。 初始化 funcp = funct_foo_name + 1;现在使用调用函数 函数指针。函数指针指向有效的虚拟地址 代码段的空间。 bt 函数将从错误的位置开始 执行。这可能导致错误的代码执行或错误 顺序。

    【讨论】:

    • 你做了太多不一定成立的假设。我曾在地址 0 与地址 42890 没有任何不同的平台上工作过。
    • 正如Ten Commandments 教导我们的那样,“你不应跟随 NULL 指针,因为混乱和疯狂等着你。”
    • @NikBougalis:你说得对。我所说的第一页或 0 到 4096 的无效地址范围(这是 x386 的标准页面大小)的意思是初始无效虚拟地址空间。我认为它是依赖于操作系统的东西,它认为虚拟地址空间范围的初始部分有多少是无效的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2015-09-06
    • 2016-03-27
    • 2021-03-23
    • 2014-01-07
    相关资源
    最近更新 更多