You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C中栈与堆地址疑问:实例代码解析请求

Objective-C内存分配地址解析

嘿,我来帮你把这些内存地址的疑惑拆解清楚,你已经做了不少研究,咱们就对着代码一个个说透:

对象指针示例解析

先看这段对象相关的代码:

NSObject *obj;
NSLog(@"%p", obj); //输出0x0,这是栈地址吗?
NSLog(@"%p", &obj); //输出0x7ffee427bf68,这是堆地址吗?
obj = [[NSObject alloc] init];
NSLog(@"%p", obj); //输出0x6000000119b0,这是栈地址吗?
NSLog(@"%p", &obj); //输出0x7ffee427bf68,这是堆地址吗?

我逐个解释每个输出的含义:

  • 第一个NSLog(@"%p", obj):这里的obj是一个指针变量,你只声明了它但没初始化,所以它的默认值是nil(也就是0x0)。这个输出不是栈地址,就是空指针的标识,表示它目前没有指向任何内存地址。
  • 第二个NSLog(@"%p", &obj):&obj取的是指针变量obj本身在内存中的地址。这个变量是存在栈上的——你看地址是0x7ffee开头,这是macOS/iOS系统中栈内存的典型地址前缀,所以这是栈地址,不是堆地址。
  • 第三个NSLog(@"%p", obj):当你执行[[NSObject alloc] init]后,系统在堆上分配了一块内存来存储NSObject实例,然后把这块堆内存的地址赋值给了obj指针。所以这个输出的0x6000开头的地址是堆地址(堆内存的地址通常是0x6000或0x1000开头),不是栈地址。
  • 第四个NSLog(@"%p", &obj):不管obj指针指向堆还是空,指针变量obj本身的存储位置(栈上)是不会变的,所以这个地址和之前的栈地址完全一样,依然是栈地址,不是堆地址。

基本类型示例解析

再看基本类型的代码:

int value = 23;
NSLog(@"%p", value); //输出0x17,这是栈地址吗?
NSLog(@"%p", &value); //输出0x7ffeea19bf6c,这也是栈地址吗?

这里要注意一个容易踩的坑:

  • 第一个NSLog(@"%p", value):这其实是错误的用法。%p格式符是用来打印指针地址的,但你传的是int类型的数值23,系统会把这个数值当成地址来解析打印。23的十六进制是0x17,所以输出的是这个数值的十六进制表示,根本不是内存地址,更不是栈地址。
  • 第二个NSLog(@"%p", &value):&value取的是int变量value本身的内存地址,基本类型变量默认存在栈上,0x7ffee开头的地址也验证了这一点,所以这确实是栈地址。

关键总结

最后给你提炼几个核心点,方便你记忆:

  • 指针变量(比如obj)本身是存储在栈上的,所以&指针变量得到的一定是栈地址。
  • 指针变量指向的内容:如果是通过alloc/new等方式创建的对象,内容存储在堆上,指针的值就是堆地址;如果是未初始化或赋值为nil,指针的值就是0x0(空指针)。
  • 基本类型变量(int、float等)默认存储在栈上,&基本类型变量得到的是栈地址;不要用%p直接打印基本类型的数值,这会导致错误的输出。

内容的提问来源于stack exchange,提问作者user7110150

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:21:23