C语言数据结构的套路

跟着DSAA in C写代码,总结起来各种数据结构大概都是这个套路:

首先是定义:

typedef struct XXXXX
{
	//数据结构包含的元素
} XXX

然后分配空间,malloc(sizeof(XXX))
对于用到数组来存储数据元素的,还要额外给数组分配空间,比如队列:
Q->array = malloc(sizeof(int) * max);
最后用完之后一定要记得free!

这个套路用途广泛,比如想要把图片作为一个数据结构,首先可以这么定义:

typedef struct ImgStruct
{
	uint8_t *data;
	int width;
	int height;
} Image;

然后导入图片(这里用了OpenCV,是C++,需要给函数包装一下才可以被C调用):

Image *image_import(char *img_name)
{
	Image *img;
	img = (Image *)malloc(sizeof(Image));
	cv::Mat img_mat = cv::imread(img_name, cv::IMREAD_GRAYSCALE);
	img->width = img_mat.cols;
	img->height = img_mat.rows;
	int img_size = img_mat.cols * img_mat.rows;
	img->data = (uint8_t *)malloc(img_size);
	//cv::imshow("image", img);
	for (int i = 0; i < img_mat.rows; i++)
	{
		for (int j = 0; j < img_mat.cols; j++)
		{
			img->data[i * img_mat.rows + j] = img_mat.at<uchar>(i, j);
		}
	}
	return img;
}

在main函数中只需要这样既可:

	Image *src;
	src = image_import("demo.bmp");

最后是free,设置NULL是防止悬空指针:

void image_free(Image *img)
{
	free(img->data);
	img->data = NULL;
	free(img);
	img = NULL;
}

强调一下悬空指针的问题,参考悬空指针(Dangling pointer)避免方法

什么是悬空指针?
一个指针所指的内存被释放后,这个指针就被悬空了。
悬空指针的危害?
访问悬空指针,结果随机。可能导致程序功能不正常,也可能导致程序崩溃。如果受到影响的是其它功能,问题通常很难定位。
如何避免悬空指针?
基本思路:在释放一块内存时,将指向这块内存的指针变量设置为NULL。访问指针变量前,先判断是否为NULL。
进阶:当有多个指针变量都指向同一块内存时,释放这块内存时,需要将所有指针变量的值都置为NULL,这需要维护所有指向这块内存的指针变量的信息,但是这种方式开销大,所以通常很少使用。使用频率不是非常高的对象,可以在使用前先根据id等索引查找,如果找不到,则不要使用。如果有使用者时,不能释放这块内存,我们可以使用引用计数,只有当引用计数为0时,才真正释放内存,否则,只是引用计数减1。

BTW,DSAA中数据结构的各种函数多是传指针作为参数,传值的方法当然也可以,两者的区别可以参考C语言 结构体传值与传址分析

结构体对象作为参数时,编译器对其进行了copy,(我们通过传入的地址和main中不同可以发现)。此时在函数中的操作都是对其拷贝的操作,不影响main函数中的origin value。缺点是,当结构体变量非常大时,编译器对其进行复制,开销较大。结构体地址作为参数时,子函数中操作和main函数操作的是同一个结构体,此时传递的参数时一个地址。优点是不需要进行copy,但是使用时要小心,如果不想修改其值,需用const关键字修饰。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值