AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题

问题[pointers](coding)

Martin Hope
ViperZer0
Asked: 2025-04-26 00:46:44 +0800 CST

Rust 如何知道智能指针类型应该有多大?

  • 8

在下面的 Rust 代码中,aBox或Rc包含 a 的u32是 8 字节,而 aBox或Rc包含一个切片的 是 16 字节。我理解这是为什么;指向动态大小内存区域(例如切片)的智能指针除了地址之外,还会包含该内存区域的长度。

fn main()
{
    println!("Size of Box<u32>: {} bytes", std::mem::size_of::<Box<u32>>()); // 8
    println!("Size of Box<[u32]>: {} bytes", std::mem::size_of::<Box<[u32]>>()); // 16
    println!("Size of Box<str>: {} bytes", std::mem::size_of::<Box<str>>()); // 16

    println!("Size of Rc<u32>: {} bytes", std::mem::size_of::<Rc<u32>>()); // 8 
    println!("Size of Rc<[u32]>: {} bytes", std::mem::size_of::<Rc<[u32]>>()); // 16
    println!("Size of Rc<str>: {} bytes", std::mem::size_of::<Rc<str>>()); // 16
}

我的问题是 Rust 的编译器如何知道指针需要多大以及如何实际使用或解释额外的长度。

首先,以下是我对指针大小的最佳猜测。 和 都Rc具有Box以下结构:

pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A);
pub struct Rc<T: ?Sized, A: Allocator = Global> {
    ptr: NonNull<RcInner<T>>,
    phantom: PhantomData<RcInner<T>>,
    alloc: A,
}

我假设该类型以某种方式为/Allocator提供了额外的 8 个字节空间作为长度,但我不知道这实际上是怎么发生的。我查看了分配器代码,但不明白在这里包含分配器实际上起了什么作用。如果我要创建自己的指针/容器类型,那么在我的结构体中包含该类型是否足以实现这种行为?BoxRcAllocator

至于长度如何使用,我的理解是和都Box<T>可以Rc<T>透明地强制为&T,并且&T是一种原始类型,编译器或多或少希望它要么是指向单个数据单元的指针,要么是指向数据数组的指针和长度,但在那种情况下,Deref实现让我感到困惑。

impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {

    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &T {
        &self.inner().value
    }
}

我感觉我本以为这会以某种方式“丢失”关于长度的信息,因为这些信息包含在 中,Rc而不是RcInner或值 中T。但事实并非如此,编译器神奇地知道,因为Rc<[T]>本身是一个指针,就像 一样&[T],它知道 的Rc地址后面也有一个隐藏的长度,尽管Rc它从未明确包含它。我知道长度并不[T]像你想象的那样存储在 中,而是存储在 的地址堆栈中[T],无论是通过Box、Rc还是简单的引用。

所以这是我的两个问题:如何在数据结构本身中定义/建立胖指针的附加数据,以及 Rust 如何知道像Rc或Box这样的类型不仅仅是一个指针,而是一个具有长度附加信息的胖指针?

这里有一些类似的问题,它们帮助我理解切片/指针/胖指针如何作为背景工作:

  • Rust 中的切片和引用有什么区别?
  • 什么是“胖指针”?
  • 切片和数组有什么区别?
pointers
  • 1 个回答
  • 68 Views
Martin Hope
kesarling
Asked: 2024-12-04 05:29:19 +0800 CST

我如何使 GHC.Ptr 成为 Monad 的实例?

  • 6

这是我目前所拥有的:

instance Monad Ptr where
    return = pure
    (>>=) (Ptr t) f = f t 

抛出的错误是:

    • Couldn't match a lifted type with an unlifted type
      When matching types
        a :: *
        GHC.Prim.Addr# :: TYPE 'GHC.Types.AddrRep
    • In the first argument of ‘f’, namely ‘t’
      In the expression: f t
      In an equation for ‘>>=’: (>>=) (Ptr t) f = f t
    • Relevant bindings include
        f :: a -> Ptr b (bound at RegionalMemory.hs:16:19)
        (>>=) :: Ptr a -> (a -> Ptr b) -> Ptr b
          (bound at RegionalMemory.hs:16:5)
   |
16 |     (>>=) (Ptr t) f = f t
   |                         ^

我不太明白这个错误。我做错了什么?

pointers
  • 1 个回答
  • 27 Views
Martin Hope
Sukram 22
Asked: 2024-09-02 23:48:07 +0800 CST

如果堆栈指针进入第二个嵌套函数,堆栈中的帧指针会发生什么情况?

  • 5

我正在尝试学习 x86。(IA-32 架构)今天我学习了 Stack。我认为我理解的是:

StackPointer (SP) 指向堆栈的“顶部”(最小地址)并存储在 ESP 寄存器中。帧指针 (FP) 可以访问参数和局部变量,因为它是“弹出地址”,因此即使 SP 在堆栈内进一步移动也是静态的。

int addSome(int arg1, int arg2);

int main(void){
  int answer = addSome(1,2);
}


int addSome(int arg1, int arg2){
  return arg1 + arg2;
}

堆栈看起来应该是这样的:

帧指针显示“弹出地址”的堆栈

如果有嵌套函数,FP 会发生什么情况?它不能上移,因为如果弹出子函数,将需要它的位置。

为了实现可视化,添加此函数,它将在 addSome() 内部调用:

int subSome(int arg3, int arg4);
int subSome(int arg3, int arg4){
  return arg3 - arg4;
}

FP 在此处如何处理?如何知道新的“弹出地址”以及新参数的位置? 堆栈中的帧指针显示第一个函数的“弹出地址”,第二个函数未知

我的猜测是 addSome 的堆栈大小将被保存在某个地方,以获取相对于 FP 的新“弹出地址”的位置:

帧指针与新“弹出地址”有相对差异的堆栈

但是堆栈大小必须保存在某个地方,如果有更多的嵌套函数,就必须有更多的地方来存储这些大小,我认为这是不可能的。

pointers
  • 1 个回答
  • 46 Views
Martin Hope
Xmaki
Asked: 2024-07-23 15:43:44 +0800 CST

结构和指针:请帮我理解这行代码

  • 5

请帮助我理解最后一行的作用:

int PCKT_LEN = 8192;

char buffer[PCKT_LEN];
  struct iphdr *ip = (struct iphdr *) buffer;
  struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct iphdr));

我知道这个,我有点理解:

(struct udphdr *)  -> Means cast to a udphdr "object"/instance or something like that.

这个我有疑问/不明白:

(buffer + sizeof(struct iphdr)) 
        
        This one, I don't quite understand. Is it because it uses the ADDRESS being returned by buffer and then adds the actual size of the buffer until the last byte as an offset before starting to allocate udp memory range?  I guess the it wants to start the address of udp right after the ip ?

如果我像下面这样执行最后一行,结果会一样吗?(我将缓冲区改为ip)

   struct udphdr *udp = (struct udphdr *) (ip + sizeof(struct iphdr));

谢谢。

问候,

X

(我是 CPP 新手,刚刚开始学习指针和结构体。)

pointers
  • 1 个回答
  • 15 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve