struct中使用char[]
缘由
最近在看redis的源码,刚开始看sds,看到这块代码
struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
char buf[];
};
好奇为什么使用 char buf[]
,而不用char *buf
,找到答案记录一下。
struct中的char*和char数组有什么区别
常用来构成缓冲区。比起指针,用空数组有这样的优势:
- 不需要初始化,数组名就是所在的偏移,当数组名作为函数参数的时候,也就是指向第一个元素的指针。
- 空数组不占用内存, 但是指针需要占用int长度的空间,不同平台,占用大小不一样。
内存连续性
- 分配内存时:如果使用空数组,则可以使用
malloc(sizeof(structXXX) + buf_len)
的方式来分配一段连续的内存。buf_len
可以直接作为 缓冲区的长度。但是如果使用的是指针,则需要额外的去给指针赋值。而此时的内存与结构体的内存已经不连续,要分别申请和释放。 - 在释放内存时,如果用数组,则一次性释放;如果用的是指针,则需要先释放struct中的指针,再释放结构体,不可以颠倒。
结构体中最后一个成员为
[1]
长度数组的用法:与长度为[0]
数组的用法相同,改写为[1]
是出于可移植性的考虑。有些编译器不支持[0]
数组,可将其改成[]
或[1]
.一般使用char []
.
代码示例:
#include <stdlib.h>
#include <stdio.h>
struct __attribute__ ((__packed__)) t_char1
{
char a;
char b[];
};
struct __attribute__ ((__packed__)) t_char2
{
char a;
char* b;
};
int main()
{
char a = 0;
char a1[]={};
char *b = &a;
t_char1 c;
t_char2 d;
printf("char: %d, char*: %d, char[]: %d\n", sizeof(a), sizeof(b), sizeof(a1));
printf("t_char1: %d, c.a: %p, c.b: %p\n", sizeof(c), &c.a, c.b);
printf("t_char2: %d, d.a: %p, d.b: %p\n", sizeof(d), &d.a, d.b);
}
__attribute__ ((__packed__))
的作用是为了取消内存对齐。
编译输出
$ g++ -o test main.cc -std=c++11
$ ./test
char: 1, char*: 8, char[]: 0
t_char1: 1, c.a: 0x7ffd906865b6, c.b: 0x7ffd906865b7
t_char2: 9, d.a: 0x7ffd906865a0, d.b: 0xa000000000004006
总结:
struct t_char1
中空数组没有分配内存,sizeof©-sizeof(a) = 1-1=0;struct t_char2
中指针的内存占用了八字节 。- 通过观察得到,在
struct t_char1
中, 空数组虽然不占用内存,但是可以获取结构体尾部的地址。 - 在结构体中更推荐使用
char[]
。
--完--
- 原文作者: 留白
- 原文链接: https://zfunnily.github.io/2021/01/chararray/
- 更新时间:2024-04-16 01:01:05
- 本文声明:转载请标记原文作者及链接