【问题标题】:Understanding dangling pointer behaviour in this case在这种情况下了解悬空指针行为
【发布时间】:2019-02-15 13:00:35
【问题描述】:

我有一个指针,默认情况下它带有 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有什么特殊含义吗?

【问题讨论】:

  • 不要对malloc返回的指针值做任何假设。 malloc 可能返回的唯一“特殊”指针值是 NULL
  • @Jabberwocky 我真的承认你的观点,但是这个编译器的目的是什么让这个值“总是”在指针中,直到现在访问一个上下文外的内存,因为我没有明确地将其设为 NULL ?
  • 我认为您应该阅读 C 教科书中有关动态内存分配和指针的章节。在free(p)之后,p没有改变,但是p没有指向任何地方,或者说,它指向了一些不再属于你的记忆你不能再取消引用p。这就是 C 语言的工作原理。

标签: c pointers dangling-pointer


【解决方案1】:

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

C 标准规定,一旦对象为freed,或者更一般地说,它的生命周期结束,所有指向该对象的指针的值就变为不确定,并且使用这样的即使只是打印值,不确定的值也会导致未定义的行为。无法保证它恰好看起来好像保留了其原始价值。

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


至于两个不同对象的内存地址相同 - 如果它们不是同时存在的话,这是可能的。单个对象将在其整个生命周期内拥有一个常量地址。未指定其生命周期后会发生什么。 malloc 通常实现为空闲块列表,最近的 freed 块很可能首先被重用。

【讨论】:

  • p 没有访问有效的内存访问,因为内存被 free 调用标记为空闲,但是你是说它是编译器优化以具有相同的值(0xFF00000000)当它们指向的内存被某个有效指针访问时,悬空指针?
  • @SUMITKUMARSINGH 啊不,我是说如果编译器可以证明,“悬空指针”需要保留其值。
  • 正确!,我担心为什么总是看到相同的值,因为我期待随机垃圾值。
  • @SUMITKUMARSINGH 在你free 之后指针是不确定的,这意味着你不能期望它是任何东西——NULL、垃圾或保留相同的地址——在你释放之后。在您调用免费的那一刻,您应该停止关心它指向的内容。
  • @Kcvin:作为一个通用扩展,许多实现——尤其是那些设计为适合低级编程或自托管的实现——将允许使用目标已被指定的指针执行某些操作释放。例如,这种实现通常还允许实现检查realloc是否移动了一个块,并假设如果新指针和旧指针相同,则不需要重新计算标识块内位置的指针,这如果 realloc() 缩小一个块并因此不太可能移动它,则可以节省时间。
【解决方案2】:

稍后我将在其他地方释放指针?确保仅在分配动态内存地址时释放 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() 可能会返回相同的地址(不是值),也可能不会。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多