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++的封闭中的析构函数会让这事easy和干净非常多)

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

连续的内存故意于提高訪问速度,也故意于降低内存碎片。

(事实上。我个人认为也没多高了,反正你跑不了要用做偏移量的加法来寻址)

*/

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

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

时间: 2024-10-10 00:39:30

c结构体里的数组与指针的相关文章

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

c#中关于结构体和字节数组转化

最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.InteropServices; namespace FileSendClient { [StructL

C#结构体和字节数组的转换函数

在通信过程中,一般我们都会操作到字节数组.特别是希望在不同语言编程进行操作的时候. 虽然C#提供了序列化的支持,不用字节数组也行.但操作字节数组肯定会碰到. 一般都会采用结构来表示字节数组.但结构与字节数组直接的转换实在很麻烦. 字节操作不但容易出错,而且每增加一个结构,就自己实现一遍,实在是烦不胜烦. 有没有简单的方法呢?当然有.可以采用非托管区的一些方法来实现. 首先,导入命名空间:System.Runtime.InteropServices; 定义结构的时候,要给结构指定特性. 如: //

c语言结构体中动态数组的使用

[背景] c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间. [正文] 1. 动态数组在结构体中间 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int a; char buf[0]; // 或者char buf[]; int b; }Node; int main() { printf("%d\n", si

宏定义放在结构体里

#include<stdio.h> struct node { #define Max(a,b) a>b?a:b//个人感觉宏定义放在结构体里和放在放在最上面是没有区别的,可能是为了读代码方便 int x,y; }; struct node2 { int x,y; }; int main() { node a; node b; scanf("%d%d",&a.x,&a.y); scanf("%d%d",&b.x,&b

C语言结构体里的成员数组和指针

struct test{ int i; char *p; }; struct test *str; int a = 1; char *b = "ioiodddddddddddd"; str = (struct test *)malloc(sizeof(struct test));//结构体指针不为null str->i = a; str->p = b; printf("%s\n",str->p); //输出ioiodddddddddddd retu

c++与C# winform的消息通讯--(结构体与byte数组的使用)

近期正在做一个蓝牙驱动的使用程序,其中有一块从c++发送数据到C#的部分,网上查了很多资料,大多都是介绍如何通过调用函数获取用户数据.并且在消息发送中,很少介绍如何发送一个结构体,并且结构体里面有 byte数组(硬件开发常用)等如何进行处理. 首先c++里面要建立一个dll文件: 1 BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) 2 { 3 switch (ul_reason

c动态分配结构体二维数组

这个问题我纠结了蛮久了,因为前面一直忙(自己也懒了点),所以没有能好好研究这个.希望这篇文章能够帮助你们. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stddef.h> 4 5 typedef struct LNode { 6 int F; 7 struct LNode* next; 8 }LNode, *LinkList; 9 int main() 10 { 11 LNode** map = (LNo

Go -- 中结构体与字节数组能相互转化

编码时如下,假设默认你的结构体为data func Encode(data interface{}) ([]byte, error) { buf := bytes.NewBuffer(nil) enc := gob.NewEncoder(buf) err := enc.Encode(data) if err != nil { return nil, err } return buf.Bytes(), nil } 解码时如下,data为需要解码的字节数组,to为相应的接收结构体,记住to的结构体结