1. char data[0]的存在形式
char data[0]的存在形式一般如下图中的伪代码所示,多数情况都是放在结构体的最后,其不占用结构的空间(sizeof(struct AAA)的结果不包含char xxx_data[0]),xxx_data[0]的存在只是一个指针的占位符,当结构体分配的指针分配的内存多于结构体本身应占有的内存时,多于的内存将会由这个 "xxx_data"的指针所指向,并且可以通过结构体去使用这块内存。
这就类似相当于结构体“包含”了一段可变长的空间,从而克服了C语言结构体类型需要有明确长度的“缺陷”。(注意:我这里的包含加了“”,因为实际并不是包含关系)。
typedef struct{
...
int xxx_len;
char xxx_data[0];
}pAAA;
2. 实例说明
(1)示例说明:
下面的示例展示了,定义了一个结构体,包含了一个int型的len和一个char data[0],然后将结构体的指针和要读取文件的路径传入read_file_data这个函数。
该函数中会根据文件的实际长度,为结构体和data[0] malloc内存。读取文件内容并给结构体成员"len" 和 "data[0]" 所指的空间赋值。
最后在main函数里输出文件的长度,和文件内容。
(2)代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILE_NAME "./test.txt"
typedef struct{
int len;
char data[0];
}str_test;
void read_file_data(char * fileName, str_test **str)
{
FILE *pFile = NULL;
size_t fileLen = 0;
size_t len = 0;
char *pHead = NULL;
pFile = fopen(fileName, "r");
if (!pFile){
return;
}
//获取文件的长度
fseek(pFile, 0, SEEK_END);
fileLen = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
//malloc时申请内存的长度=str_test结构体的程度+文件的长度+1,结构长度外的内存用于存储文件数据
*str = (str_test *)malloc(sizeof(str_test)+fileLen +1);
if (!(*str)){
return;
}
memset(*str, 0, sizeof(str_test)+fileLen+1);
(*str)->len = fileLen;
pHead = (*str)->data;
do{
len = fread(pHead, 1, 10, pFile);
pHead += len;
}while(len>0);
fclose(pFile);
}
int main(void)
{
str_test *str = NULL;
read_file_data(FILE_NAME, &str);
if (str){
printf("file_len=%d\n", str->len);
printf("file_data=%s\n", str->data);
free(str);
}
return 0;
}
(3)test.txt文件内容:
111222333 hello world 666hoihg
(4)结果: