/*
访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容
*/
/*关于长度为0的数组,柔性数组意义*/
/*第一个意义是, 方便内存释放。如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,
并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员
也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存
一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
(读到这里,你一定会觉得C++的封闭中的析构函数会让这事容易和干净很多)
第二个原因是,这样有利于访问速度。连续的内存有益于提高访问速度,也有益于减少内存碎片。
(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)
访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容
*/
struct buf_str
{
int length;
char buf[0];
};
struct foo
{
buf_str* pbuf;
};
void test_funny()
{
foo f = {0};
printf("%x\n", f.pbuf);
printf("%x\n", &f.pbuf->length);
printf("%x\n", &f.pbuf->buf);
printf("%x\n", f.pbuf->buf);
if (f.pbuf->buf) //没有申请内存,但是可以访问相对地址,*数组名就是相对地址*
{
//printf(f.pbuf->buf); //crash,等价于printf("%s", f.pbuf->buf);指针的内容
}
}
struct buf_str1
{
int length;
char *buf;
};
struct foo1
{
buf_str1* pbuf;
};
void test_funny1()
{
foo1 f = {0};
printf("%x\n", &f.pbuf->length);
printf("%x\n", &f.pbuf->buf); //指针的相对地址, 和前面的比较,也和下面的比较
printf("%x\n", f.pbuf->buf); //指针所指内容的地址,*访问指针,就是访问相对地址里面的内容* crash
if (f.pbuf->buf) //crash, 访问内容
{
printf(f.pbuf->buf);
}
}
/*关于长度为0的数组,柔性数组意义*/
/*第一个意义是, 方便内存释放。如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,
并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员
也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存
一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
(读到这里,你一定会觉得C++的封闭中的析构函数会让这事容易和干净很多)
第二个原因是,这样有利于访问速度。连续的内存有益于提高访问速度,也有益于减少内存碎片。
(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)
*/
void test_funny2()
{
printf("buf_str size : %d\n", sizeof(buf_str));//仅仅输出4,零长度的数组是存在于结构体内的,但是不占结构体的size
int buf_len = 10;
//
//长度为0数组的用法
buf_str* pBuf = (buf_str*)malloc(sizeof(buf_str) + sizeof(char)*(buf_len+1));//连续的内存
pBuf->length = buf_len+1;
memset(pBuf->buf, 'a', sizeof(char) * buf_len);
pBuf->buf[buf_len] = '\0';
printf("%d %s\n", pBuf->length, pBuf->buf);
free(pBuf);//只释放一次内存
pBuf = NULL;
//
//
//正常的申请
buf_str1* pBuf1 = (buf_str1*)malloc(sizeof(buf_str1));
(pBuf1->buf) = (char*)malloc(sizeof(char)*(buf_len+1)); //内存可能不连续,需要两次释放
pBuf1->length = buf_len+1;
memset(pBuf1->buf, 'a', sizeof(char) * buf_len);
pBuf1->buf[buf_len] = '\0';
printf("%d %s\n", pBuf1->length, pBuf1->buf);
free(pBuf1->buf);
free(pBuf1);
pBuf = NULL;
}
原文来自于
http://coolshell.cn/articles/11377.html
只不过提取了主要内容,并测验