java C语言内存占用_C语言结构体占用内存总结

C语言结构体占用内存总结

前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题。觉得以后会对小可爱有点帮助,就打算先写一下。

struct Test

{

int a;

char b;

int c;

} test;

理论上,结构体中的各个成员在内存中应该是连续储存的,就像数组里面的元素一样。事实上,也确实是这个样子的,不过和我们想象的有点不一样。

按照我们最初的想法,变量test所占的内存为 4 + 1 + 4 = 9。

但是我们写一个小代码验证一下发现和我们想的不一样。

6e8f3811c4051d115a2c476f8c7ae547.png

它的内存为12。因为 int类型是4个字节,所以是不是各个成员的内存都是按照最大的那个设置呢?毕竟 4 * 3 = 12,我们再次实验,

ccad5c81d74059b56380165c09f2cf73.png

如果按照我们的推测,那么内存大小应该是 8 * 3 = 24。为何是16呢?

下面我来总结一下。

总结

C语言结构体所占内存大小,其实里面涉及到C语言内存对齐,提高寻址效率的一种思想在里面。具体我就不在这里展开来说了,有兴趣的可以自己百度了解一下。

其实小可爱最想了解的应该是如何计算,结构体的内存大小。

不包含,数组和指针的结构体

对于不包含,数组和指针的结构体,知道各个成员所占内存大小后,可以直接相加,不过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,如果不够就补上;并且最后的结果必须要是所占内存空间最大的成员变量的整倍数。

下面我来几个例子说明:

struct Test

{

double c; //8

int a;//4

char b;//1

} test;

所占内存大小,8 + 4 + 1 = 13,最大内存为8, 所以应该这样计算 8 + 4 + 4 = 16。

下面我们交换下,

struct Test

{

int a;//4

double c; //8

char b;//1

} test;

所占内存大小, 4 + 8 + 1 = 13,因为double类型是8个字节,而前面只有4个字节,并且成员变量最大内存为8,所以应该这样计算 8 + 8 + 8 = 24。

struct Test

{

int a;//4

char b;//1

double c; //8

} test;

同理4 + 1 + 8 = 13,应该变为 4 + 4 + 8 = 16。

包含,数组和指针的结构体

包含指针的结构体

对于包含指针的结构体,可以用和上面相同的方法进行计算,一般指针的大小都是固定的4个字节(在我的电脑上,你们可能不同),因为不管什么类型的指针只需要储存地址,不需要储存地址指向空间的内容。 struct Test

{

char a;//1

char *b;//4

double c;//8

} test;

struct Test

{

char a;//1

int *b;//4

double c;//8

} test;

struct Test

{

char a;//1

double *b;//4

double c;//8

} test; 这三种所占内存大小均为 4 + 4 + 8 = 16。如果将变量 b 和变量 c 的位置互换,则变为 8 + 8 + 8 = 24。

包含数组的结构体

数组中的元素地址是连续的,所以一个数组所占空间大小,为数组类型 * 元素个数。

知道了数组所占空间大小后,再来说说如何计算结构体中包含数组的情况,在之前计算的时候,我说过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,但是如果下一变量为数组,则没有这个要求。

例如:

struct Test

{

int a;

char b[21];

int d;

double c;

} test;

应该为 4 + 24 + 4 + 8 = 40。

struct Test

{

int a;

char b[19];

int d;

double c;

} test;

应该为 4 + 20 + 8 + 8 = 40。

struct Test

{

char a;//1

char b[19];//19

int d;//4

double c;//8

} test;

应该为 1 + 19 + 4 + 8 = 32。

struct Test

{

char a;//1

char b[17];//17

int d;//4

double c;//8

} test;

应该为 1 + 19 + 4 + 8 = 32。

struct Test

{

char a;//1

char b[15];//15

int d;//4

double c;//8

} test;

应该为 1 + 15 + 8 + 8 = 32。

希望可以对你有一些帮助,记得点赞加关注哦!!!

不然下次找不到了!!!!

Java 通过 UDP 接收 C 语言结构体数组的数据的过程可以分成两个部分,分别是在 C 程序发送数据和在 Java 程序接收数据。 在 C 程序,需要将结构体数组转换成字节流,并通过 UDP 协议发送出去。具体步骤如下: 1. 定义结构体型,并创建结构体数组: ```c typedef struct { int id; char name[20]; float score; } Student; Student students[3] = {{1, "Tom", 90.5}, {2, "Jerry", 80.5}, {3, "Lucy", 85.0}}; ``` 2. 将结构体数组转换成字节流: ```c char buffer[sizeof(Student) * 3]; memcpy(buffer, students, sizeof(Student) * 3); ``` 3. 创建 UDP 套接字,将字节流发送出去: ```c int sockfd; struct sockaddr_in serveraddr; sockfd = socket(AF_INET, SOCK_DGRAM, 0); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(PORT); serveraddr.sin_addr.s_addr = inet_addr(IP); sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); ``` 在 Java 程序,需要接收 UDP 数据包并将字节流转换成结构体数组。具体步骤如下: 1. 创建 DatagramSocket 对象,指定接收端口号: ```java DatagramSocket socket = new DatagramSocket(PORT); ``` 2. 创建 DatagramPacket 对象,用于接收数据包: ```java byte[] buffer = new byte[sizeof(Student) * 3]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); ``` 3. 接收数据包: ```java socket.receive(packet); ``` 4. 将字节流转换成结构体数组: ```java Student[] students = new Student[3]; for (int i = 0; i < 3; i++) { byte[] data = Arrays.copyOfRange(buffer, i * sizeof(Student), (i + 1) * sizeof(Student)); ByteBuffer byteBuffer = ByteBuffer.wrap(data); students[i] = new Student(byteBuffer.getInt(), new String(byteBuffer.array(), 4, 20), byteBuffer.getFloat()); } ``` 其,ByteBuffer 可以方便地将字节流转换成各种数据型。由于 C 语言的 char 型是占用 1 个字节的,而 Java 的 char 型是占用 2 个字节的,因此需要将字节流的 char 型转换成 String 型。在这里,我们使用了 String 的构造函数,指定了从字节数组第 4 个位置开始读取 20 个字节,以获取 C 语言的字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值