Linux C柔性数组(零长数组)

零长数组,大小为0,一般用在结构体中(网络通信,省流),节省空间,方便善后(相对于指针类型),我们通过具体例子进行理解。

常规定长数组

objectivec 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CUR_LEN 512
#define MAX_LEN 1024

typedef struct
{
    int len;
    char data[MAX_LEN];
}St_FixedSize;

int main()
{
	St_FixedSize *fixed_size = NULL;
	//数组大小
	printf("the size of St_FixedSize:%d\n", sizeof(St_FixedSize));
	
	//申请空间并赋值
	if((fixed_size = (St_FixedSize *)malloc(sizeof(St_FixedSize))) != NULL)
	{
	    fixed_size->len = CUR_LEN;
	    memcpy(fixed_size->data, "Hello World", CUR_LEN);
	    printf("%d, %s\n", fixed_size->len, fixed_size->data);
	}
	
	//销毁
	free(fixed_size);
	fixed_size = NULL;
	
	return 0;
}

执行结果:

此结构体大小 = sizeof(int) + sizeof(char*MAX_LEN) = 4 + 1024 = 1028,但是data我们只使用了12个字节,浪费了1024 - 12 = 1012个字节的空间,缺点暴露无遗,优点是只申请了一次内存空间。

常规指针数组

objectivec 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CUR_LEN 512
#define MAX_LEN 1024

typedef struct
{
    int len;
    char *data;
}St_PointSize;

int main()
{
	St_PointSize *point_size = NULL;
	//结构体大小
	printf("the size of St_PointSize:%d\n", sizeof(St_PointSize));
	
	//申请空间并赋值
	if((point_size = (St_PointSize *)malloc(sizeof(St_PointSize))) != NULL)
	{
	    point_size->len = CUR_LEN;
		point_size->data = (char *)malloc(CUR_LEN);
		if(point_size->data != NULL)
		{
			memcpy(point_size->data, "Hello World", CUR_LEN);
	    	printf("%d, %s\n", point_size->len, point_size->data);
		}
	    
	}
	
	//销毁
    if(point_size->data)
    {
        free(point_size->data);
    }
	
	free(point_size);
	point_size = NULL;
	
	return 0;
}

执行结果为:

此结构体大小 = sizeof(int) + sizeof(不同平台不同编译器下的指针大小) = 16,空间的确节省了,但是在申请和释放的阶段都进行了两次,比较麻烦,容易引起内存泄漏问题。

柔性数组

objectivec 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CUR_LEN 512
#define MAX_LEN 1024

typedef struct
{
    int len;
    char data[0];
}St_OSize;

int main()
{
	St_OSize *Osize = NULL;
	//结构体大小
	printf("the size of St_PointSize:%d\n", sizeof(St_OSize));
	
	//申请空间并赋值
	if((Osize = (St_OSize *)malloc(sizeof(St_OSize) + CUR_LEN)) != NULL)
	{
	    Osize->len = CUR_LEN;
		memcpy(Osize->data, "Hello World", CUR_LEN);
	    printf("%d, %s\n", Osize->len, Osize->data);
	    
	}
	
	//销毁
	free(Osize);
	Osize = NULL;
	
	return 0;
}

执行结果:

结构体大小只有成员变量int len的大小,而data变量不占空间(char data[0]不同于指针),优点很明显,只申请了一次空间,也只释放了一次空间,同时也满足了节省空间的需求,另外这个结构体的空间还是连续的(大家可以打印下相应字段的地址)。

但是,柔性数组只能被>=C90的编译器支持(char data[]写法被C99支持)且并不没有被包含近C/C++的标准之中(GNU C中是允许的)。大家根据实际需要灵活使用吧。

参考

C语言0长度数组之《可变数组/柔性数组》详解 - 知乎

相关推荐
lengjingzju41 分钟前
一网打尽Linux IPC(三):System V IPC
linux·服务器·c语言
大聪明-PLUS42 分钟前
如何编写你的第一个 Linux 内核模块
linux·嵌入式·arm·smarc
知识分享小能手1 小时前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04文件压缩与解压缩知识点详解(12)
linux·学习·ubuntu
用户6135411460161 小时前
Krb5-libs-1.18.2-5.ky10.x86_64.rpm 安装失败怎么办?附详细步骤
linux
范纹杉想快点毕业2 小时前
返璞归真还是拥抱现代?——嵌入式研发中的“裸机开发”与RTOS全景解析
c语言·数据库·mongodb·设计模式·nosql
zhougl9963 小时前
Vuex 模块命名冲突:问题解析与完整解决方案
linux·服务器·apache
一世琉璃白_Y3 小时前
Ubuntu(VMware)虚拟机网络异常排查与解决方案
linux·网络·ubuntu
AI+程序员在路上4 小时前
网桥及IP转发在嵌入式linux eth0与wlan0连接使用方法
linux·tcp/ip·php
!停4 小时前
c语言动态申请内存
c语言·开发语言·数据结构
I · T · LUCKYBOOM4 小时前
1.Apache网站优化
linux·运维·服务器·网络·apache