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); } }
*/
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
只不过提取了主要内容,并测验