一 在栈中申请空间清晰展示 int a=7 和 int b=8 的地址关系与内存字节排列(对应小端存储):
#include <stdio.h>
int main() {
// 定义两个int变量int a = 7;int b = 8;// 1. 打印a和b的地址(%p为地址格式化符)printf("变量a的地址:&a = %p\n", &a);printf("变量b的地址:&b = %p\n", &b);printf("地址关系:&a %s &b\n\n", (&a > &b) ? ">" : "<"); // 验证地址大小// 2. 打印a的内存字节排列(将int\*转为char\*,按字节访问)printf("变量a = 7(十六进制:0x00000007)的内存字节排列(低地址→高地址):\n");unsigned char \*p\_a = (unsigned char \*)&a; // 用unsigned char\*逐个读取字节for (int i = 0; i < sizeof(int); i++) { printf("地址 %p:0x%02X\n", p\_a + i, \*(p\_a + i));}// 3. 打印b的内存字节排列printf("\n变量b = 8(十六进制:0x00000008)的内存字节排列(低地址→高地址):\n");unsigned char \*p\_b = (unsigned char \*)&b;for (int i = 0; i < sizeof(int); i++) { printf("地址 %p:0x%02X\n", p\_b + i, \*(p\_b + i));}return 0;}
运行结果说明(以 x86 小端环境为例)
假设运行后输出如下(地址值因系统而异,但规律固定):
plaintext
变量a的地址:&a = 0061FEAC
变量b的地址:&b = 0061FEA8
地址关系:&a > &b
变量a = 7(十六进制:0x00000007)的内存字节排列(低地址→高地址):
地址 0061FEAC:0x07 // 低地址存低位字节(0x07)
地址 0061FEAD:0x00
地址 0061FEAE:0x00
地址 0061FEAF:0x00 // 高地址存高位字节(0x00)
变量b = 8(十六进制:0x00000008)的内存字节排列(低地址→高地址):
地址 0061FEA8:0x08 // 低地址存低位字节(0x08)
地址 0061FEA9:0x00
地址 0061FEAA:0x00
地址 0061FEAB:0x00 // 高地址存高位字节(0x00)
核心结论(与之前逻辑一致)
地址关系: &a > &b (先定义的 a 地址更高,符合栈“高地址→低地址生长”规则);
内存排列:小端存储下, int 的低位字节存在低地址(如 a=7 的 0x07 在最左侧低地址, 0x00 依次向高地址排列)
以下用 C 语言代码演示堆中申请 int a=7 和 int b=8 ,并通过输出展示它们的地址关系与内存字节排列(基于 x86 小端架构,堆与栈的地址生长方向完全相反):
二 在堆申请的核心代码(用 malloc 分配堆内存)
#include <stdio.h>
#include <stdlib.h> // 包含 malloc/free 函数
int main() {
// 1. 在堆中申请两个 int 大小的空间(每个 int 4 字节)int \*a = (int \*)malloc(sizeof(int)); // 堆地址1:给 a 分配空间int \*b = (int \*)malloc(sizeof(int)); // 堆地址2:给 b 分配空间if (a == NULL || b == NULL) { // 检查堆申请是否成功(堆内存可能不足) printf("堆内存申请失败!\n"); return 1;}// 2. 给堆中的 a、b 赋值\*a = 7;\*b = 8;// 3. 打印 a、b 的堆地址(%p 输出指针地址,即堆中变量的地址)printf("堆中 a 的地址:&a = %p\n", a);printf("堆中 b 的地址:&b = %p\n", b);printf("地址关系:a 的地址 %s b 的地址\n\n", (a > b) ? ">" : "<");// 4. 打印 a 的内存字节排列(按低地址→高地址顺序)printf("a = 7(十六进制:0x00000007)的堆内存字节(低→高):\n");unsigned char \*p\_a = (unsigned char \*)a; // 转为 char\* 逐个访问字节for (int i = 0; i < sizeof(int); i++) { printf("地址 %p:0x%02X\n", p\_a + i, \*(p\_a + i));}// 5. 打印 b 的内存字节排列printf("\nb = 8(十六进制:0x00000008)的堆内存字节(低→高):\n");unsigned char \*p\_b = (unsigned char \*)b;for (int i = 0; i < sizeof(int); i++) { printf("地址 %p:0x%02X\n", p\_b + i, \*(p\_b + i));}// 6. 释放堆内存(堆不会自动回收,必须手动 free,否则内存泄漏)free(a);free(b);a = NULL; // 避免野指针b = NULL;return 0;}
二、运行结果(x86 小端环境,关键规律固定)
plaintext
堆中 a 的地址:&a = 00602010
堆中 b 的地址:&b = 00602014
地址关系:a 的地址 < b 的地址
a = 7(十六进制:0x00000007)的堆内存字节(低→高):
地址 00602010:0x07 // 低地址存低位字节 0x07
地址 00602011:0x00
地址 00602012:0x00
地址 00602013:0x00 // 高地址存高位字节 0x00
b = 8(十六进制:0x00000008)的堆内存字节(低→高):
地址 00602014:0x08 // 低地址存低位字节 0x08
地址 00602015:0x00
地址 00602016:0x00
地址 00602017:0x00 // 高地址存高位字节 0x00
三、核心结论(堆与栈的关键区别)
无论在堆还是栈, int 类型的多字节数据都按“低字节存低地址、高字节存高地址”排列:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。