struct hack和灵活的数组成员

一、struct hack
在C89中为了灵活的为字符串分配长度,出现了一种比较实用的惯用法:struct hack(此处不知道如何翻译),实际就是一种欺骗编译器而分配更多的内存来存储字符串的方法。
实现方式:

struct mystr {
    int length;
    char strs[1]; //指定长度为1
};
实际使用的时候是这样去用的:
struct mystr* str = (struct mystr*)malloc(sizeof(struct mystr) + n - 1);
if (mystr == NULL) {//堆中分配的内存无论如何一定要判断返回值
    perror("malloc error!");
    exit(EXIT_FAILURE);
}
str->lenth = n;

现在这个指针str就是一个指向一个在堆中存放,length的长度等于n,strs字符数组的长度为n的结构体。在使用的时候就可以把字符串直接复制到数组中,注意length的长度,不要越界了。

在C89的时候这种字符数组是不允许长度为0或者不填的,最少为1,所以每次操作的时候都会去-1,以保障分配的内存长度就是length一样的长度。

问题:既然这种繁琐的操作是为了实用要字符数组可根据需要分配长度为什么不使用变长数组?
答:变长数组是在运行的时候确定长度,在分配内存,这个特性就导致了变长数组也有其本身固有的缺陷,就是无法存储为静态的变量。只有运行到才分配内存,甚至都不运行越过goto语句(没有分配内存)。那实际变长数组的实用性就非常低了。

二、灵活的数组成员
鉴于在C89中比较好用的struct hack用法,于是在C99的时候,官方就做的更彻底一些,支持数组的长度为0,但是有特殊的限制,就是为了更好的满足struct hack用法,这种语法叫做灵活的数组成员:

struct mystr {
    int length;
    char strs[]; //可变的数组成员,仅C99支持
};

这样的语法就带来的方便了,每次分配长度的时候也可以省略去减1的操作。
但是我们在C语言中去为字符串分配长度的时候都习惯性的+1,比如分配支持长度为N的数组,我们一般会写char arr[N + 1]; 以此表示,数组支持的字符串的长度是N,而不是N - 1(良好的编程习惯能最大减少编码出现bug的可能)!

上面介绍了struct hack和灵活的数组成员,但是这种用法其实也是有其本身的限制的:
1、灵活的数组成员必须出现在结构的最后,而且结构体必须至少有一个其他的成员,比如上面写的int
2、赋值包含数组成员结构时,其他成员都会被赋值但不赋值灵活数组本身(堆内存,此处需要注意)
3、具有灵活的数组成员的结构时不完整类型,不完整类型缺少用于确定其所需大小的信息,sizeof在计算结构体长度的时候会忽略strs这个字符串的大小,灵活数组成员没有占用到内存空间(在堆里)
4、不完整类型不能作为其他结构的成员和数组的元素,但是数组可以包含指向具有灵活数组成员的结构的指针

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值