结构体中数组放在最后位置的问题

以下出自“C Programming FAQS”.

先看下面的代码:

struct name {
	int namelen;
	char namestr[1];
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name) - 1 + strlen(newname) + 1);
		//-1 for initial [1]; +1 for \0
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		strcpy(ret->namestr, newname);
	}
	return ret;
}
这个函数分配了一个name结构的实例并调整它的大小,以便将请求的名称置入namestr域中。

也可以把变长的元素声明为很大,而不是很小。

#define MAX 100
struct name {
	int namelen;
	char namestr[MAX];
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name) - MAX + strlen(newname) + 1);
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		strcpy(ret->namestr, newname);
	}
	return ret;
}
当然,真正安全的正确做法是使用字符指针,而不是数组。

struct name {
	int namelen;
	char *namep;
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name));
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		ret->namep = malloc(ret->namelen + 1);
		if(ret->namep == NULL) {
			free(ret);
			ret = NULL;
		}
		strcpy(ret->namep, newname);
	}
	return ret;
}
以上代码需要申请和释放没存空间两次。考虑到存储的数据类型是字符,为了保持连续性,可以直截了当的将两次malloc调用合成一次,这样也就可以只用一次调用free就能释放了。

struct name *makename(char *newname) {
	char *buf = malloc(sizeof(struct name) + strlen(newname) + 1);
	struct name *ret = (struct name *)buf;
	ret->namelen = strlen(newname);
	ret->namep = buf + sizeof(struct name);
	strcpy(ret->namep, newname);
	return ret;
}
但是,像这样用一次malloc调用将第二个区域接上的技巧只有在第二个区域是char型数组的时候才能移植。对于任何大一些的类型,对齐就变得很重要,必须保持。

C99引入了“灵活数组域”概念,允许结构的最后一个域省略数组的大小。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值