Skip to content

内存章节关于dangling指针的探讨 #11

@tgNotHouse

Description

@tgNotHouse

创建一个悬垂(dangling)指针, 保证指针满足类型内存对齐要求。该指针可能指向一个正常的变量,所以不能认为指向的内存是未初始化的。dangling实际表示`NonNull<T>`无意义,与`NonNull<T>`的本意有些违背,因为这个语义可以用None来实现。
```rust
pub const fn dangling() -> Self {
unsafe {
//取内存对齐地址作为裸指针的地址。
//调用者应保证不对此内存地址进行读写
let ptr = mem::align_of::<T>() as *mut T;
NonNull::new_unchecked(ptr)
}
}
```

该指针可能指向一个正常的变量,所以不能认为指向的内存是未初始化的。

这个dangling函数就是把指定类型的对齐值作为一个usize,再把这个usize用std::mem::transmute转为一个指针,所以是不是不能认为它指向一个可能的变量,因为这个指针的值本身还没有完成初始化。 所以在这个基础上,去说它指向的内存是否初始化,没有意义。

dangling实际表示NonNull<T>无意义,与NonNull<T>的本意有些违背,因为这个语义可以用None来实现。

既然dangling返回一个NonNull,那么这个指针绝对不是==0的

  1. 它返回的是对齐值,任何类型,即使size=0,align也不会等于0。
  2. Option<NonNull>大小是T,编译器不会为Some是NonNull的option分配额外的内存填充去当索引,因为如果这个option=0,就代表它是None。所以不可以用None实现,否则会导致UB。

比如:

    let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
    let op = Some(ptr);
    assert_eq!(op.is_none(), true);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions