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
相关产品推荐
相关产品推荐

