zoukankan      html  css  js  c++  java
  • c结构体里的数组与指针

    /*
    訪问成员数组名事实上得到的是数组的相对地址。而訪问成员指针事实上是相对地址里的内容
    */
    struct buf_str
    {
    	int  length;
    	char buf[0];
    };
    
    struct foo
    {
    	buf_str* pbuf;
    };
    
    void test_funny()
    {
    	foo f = {0};
    
    	printf("%x
    ", f.pbuf);
    	printf("%x
    ", &f.pbuf->length);
    	printf("%x
    ", &f.pbuf->buf);
    	printf("%x
    ", 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
    ", &f.pbuf->length);
    	printf("%x
    ", &f.pbuf->buf); //指针的相对地址。 和前面的比較。也和以下的比較
    	printf("%x
    ", f.pbuf->buf); //指针所指内容的地址,*訪问指针,就是訪问相对地址里面的内容*  crash
    	if (f.pbuf->buf) //crash, 訪问内容
    	{
    		printf(f.pbuf->buf);
    	}
    }




    /*关于长度为0的数组,柔性数组意义*/
    /*第一个意义是,方便内存释放。假设我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,
    并把整个结构体返回给用户。用户调用free能够释放结构体,可是用户并不知道这个结构体内的成员
    也须要free。所以你不能指望用户来发现这个事。所以,假设我们把结构体的内存以及其成员要的内存
    一次性分配好了,并返回给用户一个结构体指针。用户做一次free就能够把全部的内存也给释放掉。


    (读到这里,你一定会认为C++的封闭中的析构函数会让这事easy和干净非常多)


    第二个原因是。这样有利于訪问速度。

    连续的内存故意于提高訪问速度,也故意于降低内存碎片。
    (事实上。我个人认为也没多高了,反正你跑不了要用做偏移量的加法来寻址)

    */

    void test_funny2()
    {
    	printf("buf_str size : %d
    ", 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] = '';
    	printf("%d  %s
    ", 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] = '';
    	printf("%d  %s
    ", pBuf1->length, pBuf1->buf);
    	free(pBuf1->buf);
    	free(pBuf1);
    	pBuf = NULL;
    }



    原文来自于

    http://coolshell.cn/articles/11377.html

    仅仅只是提取了主要内容,并測验

  • 相关阅读:
    addClass 函数
    Javascript 严格模式详解
    Animated Scroll to Top
    Cross-Browser HTML5 Placeholder Text
    不要滥用div,保持代码的整洁
    Revit二次开发示例:DeleteDimensions
    Revit二次开发示例:ChangesMonitor
    IEnumerable,ICollection,IList,List之间的区别
    Revit二次开发示例:CancelSave
    Revit二次开发示例:AutoUpdate
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6791908.html
Copyright © 2011-2022 走看看