为什么MISRA C声明指针的副本可能导致内存异常?

tot*_*oto 37 c pointers memory-management misra

MISRA C 2012指令4.12是"不应使用动态内存分配".

例如,该文档提供了以下代码示例:

char *p = (char *) malloc(10);
char *q;

free(p);
q = p; /* Undefined behaviour - value of p is indeterminate */
Run Code Online (Sandbox Code Playgroud)

该文件指出:

尽管在调用free之后存储在指针中的值没有改变,但是在某些目标上,它所指向的内存不再存在,并且复制该指针的行为 可能导致内存异常.

几乎所有的句子我都很好,但结束了.由于p和q都在堆栈上分配,指针的副本如何导致内存异常?

250*_*501 44

根据标准,复制指针q = p;是未定义的行为.

阅读J.2未定义的行为状态:

使用指向生命周期结束的对象的指针的值(6.2.4).

转到那一章,我们看到:

6.2.4对象的存储持续时间

对象的生命周期是程序执行的一部分,在此期间保证为其保留存储.一个对象存在,具有一个常量地址,33)并在其整个生命周期内保留其最后存储的值.34)如果一个对象在其生命周期之外被引用,则该行为是未定义的.当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定.

什么是不确定的:

3.19.2 indeterminate value:未指定的值或陷阱表示

  • http://www.ibm.com/developerworks/library/pa-ctypes3/对陷阱表示背后的背景有一个非常好的解释. (8认同)
  • +1并且一些架构实际上说所有指针都没有指向有效内存(或者只是过去?)是陷阱表示. (5认同)
  • 作为*为什么*它是UB的重要例子,即使在没有陷阱表示的实现上,考虑如果用`q = malloc(10)替换最后一行会发生什么?if(p == q)......` (3认同)

gio*_*gim 14

一旦通过指针释放对象,所有指向该内存的指针都将变得不确定.(偶数)读取不确定的内存是未定义的行为(UB).以下是UB:

char *p = malloc(5);
free(p);
if(p == NULL) // UB: even just reading value of p as here, is UB
{

}
Run Code Online (Sandbox Code Playgroud)