【C / C++】结构体数组与链表的存储方式演示(内存对齐示例)

#include <algorithm>
#include <forward_list>
#include <iostream>
#include <string>

using namespace std;

using stunum_t = uint32_t;
using age_t = uint16_t;

const size_t NUM_OF_ENTRIES = 10;

struct personal_information {
    
    
	stunum_t student_number;
	wstring name;
	wstring gender;
	age_t age;
	wstring address;
};

struct personal_information s[NUM_OF_ENTRIES] = {
    
    
	{
    
     2020000001, L"刘一一", L"男", 18, L"上海市杨浦区江湾-五角场" },
	{
    
     2020000002, L"陈二", L"男", 17, L"广东省广州市海珠区琶洲站C出口保利世贸博展馆附近" },
	{
    
     2020000003, L"张三", L"男", 16, L"江苏省南京市栖霞区仙林大道" },
	{
    
     2020000004, L"Carol Bergling", L"Female", 18, L"Frescativägen, 114 18 Stockholm" },
	{
    
     2020000005, L"王小五", L"男", 18, L"不明" },
	{
    
     2020000006, L"赵六", L"女", 18, L"No. 2, Hsin Ann Rd, East District, Hsinchu City, Taiwan"},
	{
    
     2020000007, L"田七 aka Frank Tim-Cat", L"MTF", 17, L"22 Sze Mei Street, San Po Kong, Kowloon, Hong Kong" },
	{
    
     2020000008, L"Ben Moore", L"M", 16, L"4062 2nd St, Palo Alto, CA" },
	{
    
     2020000009, L"江戸川  コナン", L"M", 7, L"東京都米花市米花町5丁目毛利探偵事務所" },
	{
    
     2020000010, L"ミサカ10032号", L"F", 14, L"不詳" }
};
forward_list<personal_information> l;

int main() {
    
    
	cout << "Struct Member\t\tBeginning Address\tSize\tEnding Address\t\tOffset\n" << endl;
	const ptrdiff_t off_s = reinterpret_cast<ptrdiff_t>(&s[0].student_number);
	for (size_t i = 0; i < NUM_OF_ENTRIES; ++i) {
    
    
		cout << " <" << i << ">: \n" << endl;
		cout << "student_number\t\t"
			<< &s[i].student_number << "\t"
			<< sizeof(s[i].student_number) << "\t"
			<< &s[i].student_number + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&s[i].student_number) - off_s
			<< endl;
		cout << "name\t\t\t"
			<< &s[i].name << "\t"
			<< sizeof(s[i].name) << "\t"
			<< &s[i].name + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&s[i].name) - off_s
			<< endl;
		cout << "gender\t\t\t"
			<< &s[i].gender << "\t"
			<< sizeof(s[i].gender) << "\t"
			<< &s[i].gender + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&s[i].gender) - off_s
			<< endl;
		cout << "age\t\t\t"
			<< &s[i].age << "\t"
			<< sizeof(s[i].age) << "\t"
			<< &s[i].age + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&s[i].age) - off_s
			<< endl;
		cout << "address\t\t\t"
			<< &s[i].address << "\t"
			<< sizeof(s[i].address) << "\t"
			<< &s[i].address + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&s[i].address) - off_s
			<< endl;
		cout << endl;
	}

	for (size_t i = 0; i < NUM_OF_ENTRIES; ++i) l.emplace_after(l.cbefore_begin(), s[i]);
	cout << "List Node\t\tBeginning Address\tSize\tEnding Address\t\tOffset\n" << endl;
	const ptrdiff_t off_l = reinterpret_cast<ptrdiff_t>(&l.cbegin()->student_number);
	for (forward_list<personal_information>::const_iterator i = l.cbegin(); i != l.cend(); ++i) {
    
    
		cout << "student_number\t\t"
			<< &i->student_number << "\t"
			<< sizeof(i->student_number) << "\t"
			<< &i->student_number + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&i->student_number) - off_l
			<< endl;
		cout << "name\t\t\t"
			<< &i->name << "\t"
			<< sizeof(i->name) << "\t"
			<< &i->name + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&i->name) - off_l
			<< endl;
		cout << "gender\t\t\t"
			<< &i->gender << "\t"
			<< sizeof(i->gender) << "\t"
			<< &i->gender + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&i->gender) - off_l
			<< endl;
		cout << "age\t\t\t"
			<< &i->age << "\t"
			<< sizeof(i->age) << "\t"
			<< &i->age + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&i->age) - off_l
			<< endl;
		cout << "address\t\t\t"
			<< &i->address << "\t"
			<< sizeof(i->address) << "\t"
			<< &i->address + 1 << "\t"
			<< reinterpret_cast<ptrdiff_t>(&i->address) - off_l
			<< endl;
		cout << endl;
	}

	return 0;
}

在这里插入图片描述
在该运行环境下,此结构体的各成员按8字节对齐。结构体内的各个成员的存储地址,按照它们在结构体中定义的顺序,依次由低到高分配。所有不足8字节的成员变量,都要补齐剩余的字节,使得每个成员实际的占用空间至少达到8字节。
结构体数组是线性存储的,结构体数组的每个元素的首地址连续地按从低到高的顺序分配。
当结构体作为链表节点时,各节点的首地址一般不连续。
默认情况下,编译器根据编译的目标平台,来选择要按多少字节对齐。预处理器指令#pragma pack可以更改预设值。

おすすめ

転載: blog.csdn.net/COFACTOR/article/details/118094481
おすすめ