一个程序带你搞懂局部,结构体中的变量在内存中的存放逻辑

本文详细探讨了C++中局部变量在栈上的存储顺序,以及结构体变量的对齐与存放规则。通过实例展示了不同类型变量的大小、地址计算和结构体内部元素的布局特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

变量(局部,结构体中)的物理存放一键摸索

首先了解概念

  1. 变量按声明顺序在内存中顺序存放。不用对齐存放。而在结构体中声明的变量都是向 size 最大对齐存放。
  2. 普通变量存放在栈中,为连续区域。
  3. 咱使用高级语言(C++)不能直接对内存进行操作。

然后看图
在这里插入图片描述

  • 源代码
#include<iostream>
#include<string>

struct MyStruct
{
	int a;
	std::string b;
	char c;
	double d;
	MyStruct(int _a, char _c, double _d) : a(_a), c(_c), d(_d) {}
};

int main() {
	std::cout << "本测试采用 x86 编译器 (机器字长 32 位) → 处理器一次可提取 32 位数据" <<
		"\n一个地址存放 8 bit,所以 1 Byte 和 1 地址对应" << '\n';
	std::cout << std::endl;
	int a = 1, b = 2, c = 3;
	double d = 1.11;
	std::string str;
	std::cout << "输出普通变量 a, b, c 的存放位置" << '\n';
	std::cout << "int 类型变量大小为 4 个字节(32 bit) char 大小为 1 字节(8 bit)" << '\n';
	std::cout << "int a 的存放地址 " << &a << '\n';
	std::cout << "int b 的存放地址 " << &b << '\n';
	std::cout << "int c 的存放地址 " << &c << '\n';
	std::cout << "double d 的存放地址 " << &d << "\t大小为 " << sizeof(d) << " Byte" << '\n';
	std::cout << "string str 的存放地址 " << &str << "\t大小为 " << sizeof(str) << " Byte" << '\n';
	std::cout << "然而普通声明的一个 int 变量所间隔地址空间大小为 &a - &b = " <<
		reinterpret_cast<int>(&a) - reinterpret_cast<int>(&b) << " Byte" << '\n';
	std::cout << "所以 int 型变量顺序压栈时会导致 8 个地址空间空闲(浪费) 其他类型情况不一" <<
		"\n且变量存放顺序为从高地址开始存放,不用对齐存放" << '\n';
	std::cout << std::endl;

	MyStruct mystruct(1, 'c', 1.11);
	std::cout << "输出结构体中 a, b, c, d 的大小" << '\n';
	std::cout << "大小都是用十进表示" << '\n';
	std::cout << "a 的大小 " << sizeof(mystruct.a) << " Byte" << '\n';
	std::cout << "b 的大小 " << sizeof(mystruct.b) << " Byte" << '\n';
	std::cout << "c 的大小 " << sizeof(mystruct.c) << " Byte" << '\n';
	std::cout << "d 的大小 " << sizeof(mystruct.d) << " Byte" << '\n';
	std::cout << std::endl;

	std::cout << "输出结构体中 a, b, c, d 的地址" << '\n';
	std::cout << "地址都是用十六进制表示" << '\n';
	std::cout << "a 的地址 " << &mystruct.a << '\n';
	std::cout << "b 的地址 " << &mystruct.b << '\n';
	std::cout << "c 的地址 " << &mystruct.c << '\n';
	std::cout << "d 的地址 " << &mystruct.d << '\n';
	std::cout << "结构体中变量存放按声明顺序对齐(向所占空间最大看齐)存放且从低地址开始存放" << '\n';
	std::cout << std::endl;

	std::cout << "输出结构体的大小" << '\n';
	std::cout << "定义的结构体大小 " << sizeof(MyStruct) << " Byte" << '\n';
	std::cout << "创建的结构体大小 " << sizeof(mystruct) << " Byte" << '\n';
	// 下面一句又学到了 C++ 中的强制类型转换
	// reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数有完全相同的比特位。
	std::cout << "通过计算得出的结构体大小 " << reinterpret_cast<int>(&mystruct.d) - reinterpret_cast<int>(&mystruct.a)
		+ sizeof(mystruct.d) << " Byte" << '\n';

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值