b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

[释放c ++结构时的内存]

电脑杂谈  发布时间:2020-04-06 05:02:24  来源:网络整理

calloc实现_calloc 释放_calloc

假设您遇到这样的问题,有一个部落,有几个成员,每个成员有两个属性,分别是年龄和状态级别. 为了在程序中构造这样的部落对象,您将想到一种嵌套结构的方式. 众所周知,部落成员不是固定的,我们使用指针来表示成员.

因此calloc 释放,现在有两个结构,第二个结构嵌套在第一个结构中. 如何分配和管理动态内存?本文是这种类型的结构的内存管理的实践.

首先构造第一个结构,假设内部结构为INSIDE,并赋予属性a和b,则结构代码如下:

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

然后构造第二个结构,假设外部结构为OUTSIDE,因为成员的数量是动态的,所以我们构造一个变量而不是结构中的数量,然后使用内部结构指针来表示元素集,结构代码如下:

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

calloc实现_calloc 释放_calloc

数据结构构建完成. 接下来,为了使用此数据结构,我们需要创建其对象,但是如上面的代码所示,此结构不为成员分配内存,也就是说,它需要为该结构动态分配内存. 总之,有以下几种情况:

1,一个部落成员

2. 一个部落的多个成员

3. 多个部落的一名成员

4. 来自多个部落的多个成员

代码摘要,即

calloc_calloc实现_calloc 释放

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

从上面的代码中可以看到,我选择了分配内存空间的新方法. 没有问题很简单,但是要仔细考虑,这是有问题的,因为外部结构的第二个成员是一个指针,新分配给该成员的内存空间大小为4个字节.

要解决此问题,我选择的方法是对此结构重载新的运算符. 为什么不重载它,而不是直接在用户代码中分配它. 我的理由是calloc 释放,由于此数据结构是抽象的通用结构,因此它被非常频繁地调用,因此期望将复杂的内存分配给调用者来实现,最好直接封装到该结构本身中,这样可以减轻调用者的负担关于内存管理.

从以上代码还可以看出,这里需要重载的新运算符是new运算符,new运算符(n),operator new [],operator new(n)[]和in中的new运算符. 标准C ++它实际上是一个函数,其形式为void * operatornew(size_t大小). 我不会介绍这部分知识. 在Internet上查找信息很容易.

我的重新加载代码:

	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)
	{
		// 用标准new处理size错误,含size=0
		if ((size == 0) || (size%sizeof(struct _stuOutside) != 0))
		{
			return ::operator new(size);
		} 
		while (1)	// 无限循环处理
		{
			void *p = malloc(size);
			if (p != 0) 
			{
				int cnt = size/sizeof(struct _stuOutside);
				for (int i=0;i<cnt;i++)
				{
					struct _stuOutside *pp = (struct _stuOutside *)p + i;
					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, const int x)  
	{ 
		// 用标准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 = x;
				pp->element = (INSIDE *)malloc(x * 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, const int x)  
	{ 
		// 用标准new处理size错误,含size=0
		if ((size == 0) || (size%sizeof(struct _stuOutside) != 0))
		{
			return ::operator new(size);
		} 
		while (1)	// 无限循环处理
		{
			void *p = malloc(size);
			if (p != 0) 
			{
				int cnt = size/sizeof(struct _stuOutside);
				for (int i=0;i<cnt;i++)
				{
					struct _stuOutside *pp = (struct _stuOutside *)p + i;
					pp->count = x;
					pp->element = (INSIDE *)malloc(x * sizeof(INSIDE));
				}
				return  p;	// 分配成功后返回指针
			}
			new_handler curhandler = set_new_handler(0);  
			set_new_handler(curhandler);
			if (curhandler != 0)  
				(*curhandler)();  
			else   
				throw std::bad_alloc();
		}
	} 

calloc 释放_calloc实现_calloc

上面的代码比较简单,我的知识在这里提供了一个想法,我将不对其进行详细阐述,有兴趣的朋友可以留言与我交流. 唯一值得注意的是,最好处理内存分配异常处理,很多朋友会忽略

			new_handler curhandler = set_new_handler(0);  
			set_new_handler(curhandler);
			if (curhandler != 0)  
				(*curhandler)();  
			else   
				throw std::bad_alloc();
尽管在通常情况下,程序不是存在问题,但是一旦发生异常,就会非常麻烦,尤其是对于调用方来说,解决问题的压力更大.

以下是我编写的完整测试代码:

// testStructMemeryAllocate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <new>
#include <iostream>
using namespace std;
typedef struct _stuInside
{
	int a;
	int b;
} INSIDE;
typedef struct _stuOutside
{
	int count;
	INSIDE *element;
	//////////////////////////////////////////////////////////////////////////
	// new - delete
	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)
	{
		// 用标准new处理size错误,含size=0
		if ((size == 0) || (size%sizeof(struct _stuOutside) != 0))
		{
			return ::operator new(size);
		} 
		while (1)	// 无限循环处理
		{
			void *p = malloc(size);
			if (p != 0) 
			{
				int cnt = size/sizeof(struct _stuOutside);
				for (int i=0;i<cnt;i++)
				{
					struct _stuOutside *pp = (struct _stuOutside *)p + i;
					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, const int x)  
	{ 
		// 用标准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 = x;
				pp->element = (INSIDE *)malloc(x * 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, const int x)  
	{ 
		// 用标准new处理size错误,含size=0
		if ((size == 0) || (size%sizeof(struct _stuOutside) != 0))
		{
			return ::operator new(size);
		} 
		while (1)	// 无限循环处理
		{
			void *p = malloc(size);
			if (p != 0) 
			{
				int cnt = size/sizeof(struct _stuOutside);
				for (int i=0;i<cnt;i++)
				{
					struct _stuOutside *pp = (struct _stuOutside *)p + i;
					pp->count = x;
					pp->element = (INSIDE *)malloc(x * 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 delete(void *p)
	{
		if (p == 0)	//	 检查空指针
		{
			return ;
		}
		struct _stuOutside *pp = (struct _stuOutside *)p;
		if (pp->element != 0)
		{
			free(pp->element);	// 释放成员内存
		}
		free(p);	// 释放自身内存
	}
	// 释放数组内存时,要求必须先调用delete[]对每个元素进行释放,然后再调用delete对整体数组释放
	static void operator delete[] (void *p)
	{
		if (p == 0)	//	 检查空指针
		{
			return ;
		}
		struct _stuOutside *pp = (struct _stuOutside *)p;
		if (pp->element != 0)
		{
			free(pp->element);	// 释放成员内存
			pp->count = 0;
			pp->element = 0;
		}
	}
} OUTSIDE;
int _tmain(int argc, _TCHAR* argv[])
{
	//////////////////////////////////////////////////////////////////////////
	cout<<"test new"<<endl;
	OUTSIDE *p1 = new OUTSIDE;
	cout<<p1->count<<endl;
	INSIDE t;
	t.a = 0;
	t.b = 9;
	p1->element[0] = t;
	for (int i=0;i<p1->count;i++)
	{
		cout<<p1->element[i].a<<":"<<p1->element[i].b<<endl;
	}
	delete p1;
	cout<<endl;
	//////////////////////////////////////////////////////////////////////////
	cout<<"test new(x)"<<endl;
	OUTSIDE *p2 = new (2) OUTSIDE;
	cout<<p2->count<<endl;
	INSIDE t1,t2;
	t1.a = 1;
	t1.b = 11;
	t2.a = 2;
	t2.b = 22;
	p2->element[0] = t1;
	p2->element[1] = t2;
	for (int i=0;i<p2->count;i++)
	{
		cout<<p2->element[i].a<<":"<<p2->element[i].b<<endl;
	}
	delete p2;
	cout<<endl;
	//////////////////////////////////////////////////////////////////////////
	cout<<"test new[]"<<endl;
	OUTSIDE *p3 = new OUTSIDE[2];
	cout<<"0:"<<p3[0].count<<endl;
	cout<<"1:"<<p3[1].count<<endl;
	INSIDE t3,t4;
	t3.a = 3;
	t3.b = 33;
	t4.a = 4;
	t4.b = 44;
	p3[0].element[0] = t3;
	p3[1].element[0] = t4;
	for (int j=0;j<2;j++)
	{
		for (int i=0;i<p3[j].count;i++)
		{
			cout<<j<<":"<<p3[j].element[i].a<<":"<<p3[j].element[i].b<<endl;
		}
	}
	delete []p3;
	delete [](p3+1);
	delete p3;
	cout<<endl;
	//////////////////////////////////////////////////////////////////////////
	cout<<"test (x)new[]"<<endl;
	OUTSIDE *p4 = new (2)OUTSIDE[2];
	cout<<"0:"<<p4[0].count<<endl;
	cout<<"1:"<<p4[1].count<<endl;
	INSIDE t5,t6,t7,t8;
	t5.a = 5;
	t5.b = 55;
	t6.a = 6;
	t6.b = 66;
	t7.a = 7;
	t7.b = 77;
	t8.a = 8;
	t8.b = 88;
	p4[0].element[0] = t5;
	p4[0].element[1] = t6;
	p4[1].element[0] = t7;
	p4[1].element[1] = t8;
	for (int j=0;j<2;j++)
	{
		for (int i=0;i<p4[j].count;i++)
		{
			cout<<j<<":"<<p4[j].element[i].a<<":"<<p4[j].element[i].b<<endl;
		}
	}
	delete []p4;
	delete [](p4+1);
	delete p4;
	cout<<endl;
	//////////////////////////////////////////////////////////////////////////
	cout<<"the end !"<<endl;
	return 0;
}

结果如下:

calloc_calloc实现_calloc 释放

在调试过程中监视内存的分配和释放,如下所示:

分配内存使用后,内存状况:

用尽后,释放内存后,内存状况:

从图中可以看出,内存的释放是正常的,并且没有遗漏,尽管成员的内存地址不是通用数组那样的连续地址. 这样可以确保调用方调用的数据结构是内存安全的.

释放与c ++结构相关的内存


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-165531-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 杜红香
        杜红香

        结果大家认为捡垃圾的马云说的是屁话

      热点图片
      拼命载入中...