了解这种情况下的悬空指针行为

时间:2018-09-11 04:52:18

标签: c pointers dangling-pointer

我有一个指针,默认情况下它带有 NULL ,然后它等待某个事件,并在事件发生时获取值,稍后我将释放指针 ,但是即使释放了指针我也不将其设为NULL ,所以它仍然保持引用相同的内存位置,而且我知道下一个malloc调用可能将该内存块分配给其他一些内存请求!

pointer_type *p = NULL;
while (process_get_wakeup(//some logic//)) { 
        while ((qelem = (void*)process_dequeue(//some logic//)) != NULL) {
           p = (pointer_type *)qelem;
        }
        .
        .
        //goes into a loop of calls where free(p) is also done!
        .
        .
        //Printing value of p as %p gives this : 0xFF00000000

编辑:我已经不知道我们应该怎么做,而且我不能指望保留与现在可能用于其他用途的相同值,但是我想要的是知道为什么我只能看到 p 的特定值!

该值是否: 0xFF00000000 呈现任何特殊含义?

2 个答案:

答案 0 :(得分:3)

相反-指针在free之后 not 保持其值。

C标准规定,对象free d或更普遍地,其生命周期结束时,指向该对象的所有指针的值将变为 indeterminate ,并使用这样的不确定值可能导致不确定的行为,即使它只是打印该值也是如此。看起来它似乎保留了其原始值,这是绝对无法保证的。

这允许C编译器在函数中进行优化。例如,如果它使用一个 CPU寄存器来保留p的值,则在free(p)调用之后,编译器知道该寄存器现在可以用于其他用途,例如存储其他操作的中间计算结果的示例,在分配新值之前,不需要存储其值。


关于两个不同对象的内存地址相同-如果它们不同时存在,则可能。单个对象在整个生命周期中将具有一个恒定地址。生命周期不确定后会发生什么。 malloc通常被实现为空闲块的列表,最近的free d个块很可能会首先被重用。

答案 1 :(得分:0)

后来我在其他地方释放了指针吗?确保仅在p分配了动态内存地址后释放它,否则会导致未定义的行为。

p = NULL; /* now it's points to NULL */
p = malloc(SIZE); /* malloc() may give same previews memory location or may not */

根据 C标准,第6.2.4节

  

对象的生存期是程序执行期间的一部分   保证为其保留哪个存储。存在一个对象,   具有恒定的地址,并在整个过程中保留其最后存储的值   它的一生。如果在生命周期之外引用对象,则   行为是不确定的。指针的值不确定   当它指向(或刚刚过去)的对象到达其末端时   一生。

还有

  

我不能期望保留与可能用于相同的值   现在还有其他东西吗?

您不能强迫malloc()在释放后不返回相同的旧内存地址。释放的内存不再属于您的程序,下次当您的进程再次尝试分配内存时,malloc()可能返回相同的地址(不是值),也可能不返回。