c结构体里的数组与指针

22 篇文章 0 订阅
/*
访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容
*/
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

只不过提取了主要内容,并测验

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值