我是靠谱客的博主 年轻手机,最近开发中收集的这篇文章主要介绍大端小端 内存对齐 内存四(五)区,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

大端小端
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
https://baike.baidu.com/item/%E5%A4%A7%E5%B0%8F%E7%AB%AF%E6%A8%A1%E5%BC%8F/6750542?fromtitle=%E5%A4%A7%E7%AB%AF%E5%B0%8F%E7%AB%AF&fromid=15925891&fr=aladdin

检查大端小端的方式

int main() {
union test {
int a;
char b;
};
union test t1;
t1.a = 1;
if (t1.b == 1) {
cout << "small" << endl;
} else {
cout << "big" << endl;
}
int a = 1;
char *pa = (char *) (&a);
if ((*pa) == 1) {
cout << "small" << endl;
} else {
cout << "big" << endl;
}
}

https://blog.csdn.net/gyyu32g/article/details/79097169

以下程序的输出结果为:


typedef struct TestData_ {
unsigned int data1 : 2;
unsigned int data2 : 12;
unsigned int data3 : 2;
} TestData;
int main()
{
TestData data;
memset(&data, 0, sizeof(data));
data.data1 = 0x7;
data.data2 = 0x10;
data.data3 = 0x1;
unsigned int result = *(unsigned int *)&data;
printf("value = 0x%.8x", result); // 0x00004043
char str[] = "hello";
cout << sizeof(str) <<endl; // 6
return 0;
}

#pragma pack(n) //规定按多大进行对齐
第一个成员在结构体变量偏移量为0 的地址处,其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值。32位机器下vs中默认值是8,Linux默认值为4,64位机器下vs中默认值是8,Linux默认值为8.。注意,此处是该成员的大小。
结构体总大小为最大对齐数的整数倍。最大对齐数为:最大结构体成员变量和对齐数中的最小值,每个成员变量都有自己的对齐数。
如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。

对齐数 = 编译器默认对齐数与该成员大小中的较小值
最大对齐数 = 所有对齐数中的最大值。

可以查看编译器的默认的对齐数

struct B{
double
b;
char
c;
};
//sizeof(struct B)=16
#pragma pack (16)
struct C{
double
b[10];
char
c;
};
//此处sizeof(struct C)=88,成员变量为数组的话,对齐数算单个成员,不算数组总大小。
struct C{
char
a;
//char
c;
//char
d;
double
b;
};
struct D{
double
a;
char
c;
struct C d;
};
//此处sizeof(struct D)=32,加不加char c和char d没有影响
const int MAX_BUFF = 256;
void foo(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; ++i) {
cout << argv[i];
}
}
#pragma pack (16)
struct A{
int
a;
char
b;
short
c;
};
struct B{
char
b;
int
a;
short
c;
};
struct C{
char
a;
char
c;
char
d;
double
b;
};
struct D{
double
a;
char
c;
struct C d;
};
int main(int argc, char *argv[])
{
printf("%dn", sizeof(struct A));
printf("%dn", sizeof(struct B));
printf("%dn", sizeof(struct D));
cout<<sizeof(struct A)<<endl;
cout<<sizeof(struct B)<<endl;
cout<<sizeof(struct C)<<endl;
return 0;
int maxNum = argc;
if (maxNum > MAX_BUFF) {
maxNum = MAX_BUFF;
}
foo(maxNum, argv);
return argc;
}

结构体中包含位域的,计算结构体大小

typedef struct TestData_ {
unsigned int data1 : 1;
//unsigned int data2 : 30; // sizeof = 4
unsigned int data2 : 31; // sizeof = 8
unsigned int data3 : 1;
} TestData;
int main(void) {
TestData data;
memset(&data, 0, sizeof(data));
cout << sizeof(TestData) << endl;
}

成员变量对齐,就按照位域大小对齐。
结构体大小按照原有最大对齐数对齐。

其实“内存四区”和“内存五区”指的东西都是完全一样的
内存五区为:栈区、堆区、全局区(静态区)、常量区、代码区
内存四区为:栈区、堆区、数据区(全局区(静态区)、常量区)、代码区
因此从上面可以看出,对于内存四区而言,其只是把全局区(静态区)和常量区合并为一个数据区而已,其实内容都是完全一样的

栈区
栈区主要存放局部变量、函数调用参数等
栈区由编译器自动分配和释放
栈属于 计算机系统的数据结构,进栈出栈有相应的计算机指令支持,而且分配专门的寄存器 存储栈的地址,效率分高,内存空间是连续的,但栈的内存空间有限
堆区
使用malloc()/new()申请的内容存储在堆区
堆区由程序员手动分配,因此需要自己释放,如果不释放就会产生内存的泄漏
内存空 间几乎没有限制,内存空间不连续,因此会产生内存碎片。操作系统有一个记录空间 内存的链表,当收到内存申请时遍历链表,找到第一个空间大于申请空间的堆节点, 将该节点分配给程序,并将该节点从链表中删除。一般,系统会在该内存空间的首地 址处记录本次分配的内存大小,用于 delete 释放该内存空间
全局区(静态区)
全局区分为两个段:
DATA段:存储初始化的全局变量、初始化的静态变量
BSS段:存储未初始化的全局变量、未初始化的静态变量
其中BSS段会在程序执行前,将内容全部置为0,所以未初始化的全局变量和未初始化的静态变量的值都为0
常量区
存放常量,而且不允许修改
程序结束之后由系统释放
代码区
主要存放程序中的代码(二进制),属性是只读

https://my.oschina.net/u/4406675/blog/4467937
https://blog.csdn.net/qq_41453285/article/details/107744570

最后

以上就是年轻手机为你收集整理的大端小端 内存对齐 内存四(五)区的全部内容,希望文章能够帮你解决大端小端 内存对齐 内存四(五)区所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部