【问题标题】:Dereferencing a NULL pointer in embedded在嵌入式中取消引用 NULL 指针
【发布时间】:2017-12-19 14:48:44
【问题描述】:

我在我的项目中使用 Renesas V850 系列微控制器。 我的产品使用与主程序部分分开的非易失性内存块(NVRam 块)位置。在运行期间,会监控这些 NVRam 块以验证它们没有损坏。这个检查是用类似于下面给出的代码完成的:

逻辑 1

if((NULL != pBlock_One_Pointer) &&  (BLOCK_ONE_ID != *(((const tUI8*)pBlock_One_Pointer) + ID_OFFSET))) 
{
.....Do some corrective action....
}

此代码的问题是,如果指针“pBlock_One_Pointer”不知何故被值“NULL”损坏,则 Block_ID 检查(“if”语句的第二部分未完成)。

避免这种情况的一种方法是删除“if”条件的第一部分,它检查 Block_ID 而不管指针是否为“NULL”,如下所示

逻辑 2

if (BLOCK_ONE_ID != *(((const tUI8*)pBlock_One_Pointer) + ID_OFFSET))

但是如果“pBlock_One_Pointer”指向NULL,会不会引发异常?

所以基本上我有两个问题:

  1. 是否有可能由于运行时的某些损坏而导致指针变为 NULL 指针?
  2. 如果是这样,Logic 2 会帮助我克服它吗?

【问题讨论】:

  • 您注意到格式问题了吗?编辑问题时,有一个方便的“预览”部分。
  • "pBlock_One_Pointer" 不知何故被值 "NULL" 破坏,因此 "Do some Corrective action"` 的 if() 也应该接受 NULL。示例if((NULL == pBlock_One_Pointer) || ...
  • Re 1,如果您的代码包含导致其的错误,它可能只会错误地变为 NULL - 但是可能有 40 亿个其他值可能同样不正确,更有可能且未检查为了。真正的解决方案不是编写损坏数据的代码,那么您就无需检查是否损坏。想一想——你写了坏软件,所以你要写更多软件来检查坏软件的效果——这张图有什么问题!?

标签: c pointers embedded non-volatile


【解决方案1】:

但是如果“pBlock_One_Pointer”指向NULL,会不会引发异常?

它会导致未定义的行为。

根据the C standard6.5.3.2 地址和间接运算符

一元* 运算符表示间接。如果操作数指向 一个函数,结果是一个函数指示符;如果它指向 一个对象,结果是一个指定对象的左值。
如果操作数的类型为“指向 type 的指针”,则结果为 键入“type”。如果分配了无效值 指针,一元 * 运算符的行为是 未定义。

所以:

是否有可能由于运行时的某些损坏而导致指针变为 NULL 指针?

是的。有可能。

如果是这样,逻辑 2 会帮助我克服它吗?

没有。怎么可能?您要检查是否损坏的内存位置已丢失。

【讨论】:

  • “它会导致未定义的行为”是不正确或有帮助的,因为问题不是关于 C 语言,而是关于特定的实现。 *NULL 在 Renesas V850 上的行为是明确定义的(可能取决于确切的硬件和软件配置)。
【解决方案2】:

是否有可能由于运行时的某些损坏而导致指针变为 NULL 指针?

是的,有几件事可能会导致这种情况。软件问题,例如指针错误、失控代码、堆栈溢出等。此外,由于数据保留、EMI(现在不太可能)或环境辐射/宇宙射线而导致内存硬件故障。

如果是这样,逻辑 2 会帮助我克服它吗?

没有。有多种方法可以检测损坏的 RAM,最常见的是 CRC 校验和。

要检测故障的内存硬件,还有其他方法,例如“行走模式”,您可以通过定期向它们写入 1 和 0 来循环单元格。然而,在现代嵌入式系统中,使用内置ECC 的内存,因此软件无需担心内存硬件完整性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-14
    • 2017-04-17
    • 1970-01-01
    • 2016-03-03
    • 2017-01-29
    • 2011-10-06
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多