C/C++ 嵌套结构体动态内存管理实现

假设遇到这样一个问题,有一个部落,存在若干个成员,每个成员有两个属性分别是年龄和地位等级。在程序中为构造这样一个部落对象,会想到嵌套结构体的方式。已知部落成员不是固定的,我们对成员这个对象采用指针来表示。

那么现在就有两个结构体,第二个结构体嵌套第一个结构体,要如何进行动态内存分配和管理呢?本文就是对该类结构体的内存管理进行的实践。

首先构造第一个结构体,假设内结构体INSIDE,属性a和b,那么结构体代码如下:

typedef struct _stuInside
{
	int a;
	int b;
} INSIDE;

然后构造第二个结构体,假设为外结构体OUTSIDE,由于成员数量是动态的,因此我们在该结构体中构造一个变量代替数目,然后用内结构体指针表示元素集合,结构体代码如下:

typedef struct _stuOutside
{
	int count;
	INSIDE *element;
} OUTSIDE;

数据结构构造完成,接下来为了使用这一个数据结构我们需要创建其对象,但是如上代码所示,这个结构体是没有给成员分配好内存的,也就是需要为结构体动态分配内存。大致归纳下有以下几种场景:

1、一个部落一个成员

2、一个部落多个成员

3、多个部落一个成员

4、多个部落多个成员

抽象到代码,就是

OUTSIDE *p = new OUTSIDE;
OUTSIDE *p = new (n) OUTSIDE;
OUTSIDE *p = new OUTSIDE[n];
OUTSIDE *p = new (n) OUTSIDE[n];

从上述代码可以看到我选择的是new的方式分配内存空间,简单起来没有问题,但是仔细想下,这样是有问题的,因为外结构体的第二个成员是指针,new分配的给该成员的内存空间大小是4个字节。

要想解决这个问题,我选择的方法是为该结构体重载new操作符,为什么去重载而不是直接在使用者代码中分配呢,我的理由是既然这个数据结构是抽象的通用结构,那么被调用是很频繁的,预期将复杂的内存分配给调用者实现,还不如直接封装到结构体自身,这样可以减少调用者对内存管理的负担。

从上述代码也可以看出来,这里需要重载的new操作符有,operator new、operator new(n)、operator new[]、operator new(n)[],在标准C++中new操作符实际是个函数,其形式是void * operator new(size_t size),对这部分知识就不介绍了,网上很容易找到资料。

我的重载代码:

	static void * operator new(size_t size)
	{
		// 用标准new处理size错误,含size=0
		if (size != sizeof(struct _stuOutside))
		{
			return ::operator new(size);
		} 

		while (1)	// 无限循环处理
		{
			void *p = malloc(size);

			if (p != 0) 
			{
				struct _stuOutside *pp = (struct _stuOutside *)p;
				pp->count = 1;
				pp->element = (INSIDE *)malloc(sizeof(INSIDE));

				return  p;	// 分配成功后返回指针
			}

			new_handler curhandler = set_new_handler(0);  
			set_new_handler(curhandler);

			if (curhandler != 0)  
				(*curhandler)();  
			else   
				throw std::bad_alloc();
		}
	}

	static void * operator new[] (size_t size)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值