当前位置: 首页 > news >正文

医院图书馆网站建设的意义安徽省建设厅网站电话

医院图书馆网站建设的意义,安徽省建设厅网站电话,wordpress+搭建知识库,lnmpa安装wordpress1. malloc和free C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放。这些函数维护一个可用内存池。当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存,并向该…

1. malloc和free

C函数库提供了两个函数,mallocfree,分别用于执行动态内存分配和释放。这些函数维护一个可用内存池。当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。如果对这块内存进行初始化非常重要,要么自已动手对它进行初始化,要么使用calloc函数(在下一节描述)。当一块以前分配的内存不再使用时,程序调用free函数把它归还给内存池供以后之需。

这两个函数的原型如下所示,它们都在头文件stdlib.h中声明。

void *malloc( size_t size );
void free( void *pointer );

malloc的参数就是需要分配的内存字节(字符)数 。如果内存池中的可用内存可以满足这个需求,malloc就返回一个指向被分配的内存块起始位置的指针。

malloc所分配的是一块连续的内存。例如,如果请求它分配100个字节的内存,那么它实际分配的内存就是100个连续的字节,并不会分开位于两块或多块不同的内存。同时,malloc实际分配的内存有可能比你请求的稍微多一点。但是,这个行为是由编译器定义的,所以你不能指望它肯定会分配比你的请求更多的内存。

如果内存池是空的,或者它的可用内存无法满足你的请求,会发生什么情况呢?在这种情况下,malloc函数向操作系统请求,要求得到更多的内存,并在这块新内存上执行分配任务。如果操作系统无法向malloc提供更多的内存,malloc就返回一个NULL指针。因此,对每个从malloc返回的指针都进行检查,确保它并非NULL是非常重要的。

free的参数必须要么是NULL,要么是一个先前从malloccallocrealloc(稍后描述)返回的值。向free传递一个NULL参数不会产生任何效果。

malloc又是如何知道所请求的内存需要存储的是整数、浮点值、结构还是数组呢?它并不知情——malloc返回一个类型为void *的指针,正是缘于这个原因。标准表示一个void *类型的指针可以转换为其他任何类型的指针。但是,有些编译器,尤其是那些老式的编译器,可能要求在转换时使用强制类型转换。

对于要求边界对齐的机器,malloc所返回的内存的起始位置将始终能够满足对边界对齐要求最严格的类型的要求。

2. calloc和realloc

另外还有两个内存分配函数,callocrealloc。它们的原型如下所示:

void *calloc( size_t num_elements, size_t element_size );
void realloc( void *ptr, size_t new_size );

calloc也用于分配内存。malloccalloc之间的主要区别是后者在返回指向内存的指针之前把它初始化为0。这个初始化常常能带来方便,但如果程序只是想把一些值存储到数组中,那么这个初始化过程纯属浪费
时间。callocmalloc之间另一个较小的区别是它们请求内存数量的方式不同。calloc的参数包括所需元素的数量和每个元素的字节数。根据这些值,它能够计算出总共需要分配的内存。

realloc函数用于修改一个原先已经分配的内存块的大小。使用这个函数,可以使一块内存扩大或缩小。如果它用于扩大一个内存块,那么这块内存原先的内容依然保留,新增加的内存添加到原先内存块的后面,新内存并未以任何方法进行初始化。如果它用于缩小一个内存块,该内存块尾部的部分内存便被拿掉,剩余部分内存的原先内容依然保留。

如果原先的内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上。因此,在使用realloc之后,就不能再使用指向旧内存的指针,而是应该改用realloc所返回的新指针。

最后,如果realloc函数的第1个参数是NULL,那么它的行为就和malloc一模一样。

3. 使用动态分配的内存

这里举一个例子:

int *pi;
pi = malloc(100);
if (pi == NULL)
{printf("Out of memory!\n");exit(1);
}

符号NULL定义于stdio.h,它实际上是字面值常量0。它在这里起着视觉提醒器的作用,提醒我们进行测试的值是一个指针而不是整数。

如果内存分配成功,那么我们就拥有了一个指向100个字节的指针。在整型为4个字节的机器上,这块内存将被当作25个整型元素的数组,因为pi是一个指向整型的指针。

如果目标就是获得足够存储25个整数的内存,这里有一个更好的技巧来实现这个目的。

pi = malloc( 25 * sizeof( int ) );

这个方法更好一些,因为它是可移植的。即使是在整数长度不同的机器上,它也能获得正确的结果。

既然已经有了一个指针,那么该如何使用这块内存呢?当然,可以使用间接访问和指针运算来访问数组的不同整数位置,下面这个循环就是这样做的,它把这个新分配的数组的每个元素都初始化为0:

int *pi2, i;
pi2 = pi;
for (i = 0; i < 25; ++i)
{*pi2++ = 0;
}

不仅可以使用指针,也可以使用下标。下面的第2个循环所执行的任务和前面一个相同。

int *pi2, i;
pi2 = pi;
for (i = 0; i < 25; ++i)
{pi2[i] = 0;
}

4. 常见的动态内存错误

在使用动态内存分配的程序中,常常会出现许多错误。这些错误包括对NULL指针进行解引用操作、对分配的内存进行操作时越过边界、释放并非动态分配的内存、试图释放一块动态分配的内存的一部分以及一块动态内存被释放之后被继续使用。

动态内存分配最常见的错误就是忘记检查所请求的内存是否成功分配。这种问题显而易见:被访问的内存可能保存了其他变量的值。对它进行修改将破坏那个变量,修改那个变量将破坏存储在那里的值。这种类型的bug非常难以发现。下面的程序展现了一种技巧,可以很可靠地进行这个错误检查。MALLOC宏接受元素的数目能及每种元素的类型,计算总共需要的内存字节数,并调用alloc获得内存。alloc调用malloc并进行检查,确保返回的指针不是NULL。

这个方法最后一个难解之处在于第1个非比寻常的#define指令。它用于防止由于其他代码块直接塞入程序而导致的偶尔直接调用malloc的行为。增加这个指令以后,如果程序偶尔调用了malloc,程序将由于语法错误而无法编译。在alloc中必须加入#undef指令,这样它才能调用malloc而不至于出错。

  • alloc.h:错误检查分配器:接口
/*
** 定义一个不易发生错误的内存分配器。
*/
#include < stdlib.h>
#define malloc //不要直接调用malloc!
#define MALLOC(num,type) (type *)alloc( (num) * sizeof(type) )
extern void *alloc( size_t size );
  • alloc.c:错误检查分配器:实现
/*
** 不易发生错误的内存分配器的实现
*/
#include <stdio.h>
#include "alloc.h"
#undef malloc
void *
alloc( size_t size )
{
void *new_mem;
/*
** 请求所需的内存,并检查确实分配成功
*/
new_mem = malloc( size );
if( new_mem == NULL ){
printf( "Out of memory!\n" );
exit( 1 );
}
return new_mem;
}
  • a_client.c:使用错误检查分配器
/*
** 一个使用很少引起错误的内存分配器的程序
*/
#include "alloc.h"
void
function()
{int *new_memory;
/*
** 获得一串整型数的空间
*/
new_memory = MALLOC( 25, int );
/* ... */
}

动态内存分配的第二大错误来源是操作内存时超出了分配内存的边界。例如,如果得到一个25个整型的数组,进行下标引用操作时如果下标值小于0或大于24将引起两种类型的问题。这种问题就不是那么明显。在malloc和free的有些实现中,它们以链表的形式维护可用的内存池。对分配的内存之外的区域进行访问可能破坏这个链表,这有可能产生异常,从而终止程序

当使用free时,可能出现各种不同的错误。传递给free的指针必须是一个从malloccallocrealloc函数返回的指针。传给free函数一个指针,让它释放一块并非动态分配的内存可能导致程序立即终止或在晚些时候终止。试图释放一块动态分配内存的一部分也有可能引起类似的问题,像下面这样:

/*
** 获得10个整型内存空间
*/
pi = malloc( 10 * sizeof(int)) ;
/*
** 释放最后5个整型类型的内存空间,保留前5个内存空间
*/
free(pi +5);
}

释放一块内存的一部分是不允许的。动态分配的内存必须整块一起释放。但是,realloc函数可以缩小一块动态分配的内存,有效地释放它尾部的部分内存。

必须小心在意,不要访问已经被free函数释放了的内存。这个警告看上去很显然,但这里仍然存在一个很微妙的问题。假定对一个指向动态分配的内存的指针进行了复制,而且这个指针的几份拷贝散布于程序各处。无法保证当使用其中一个指针时它所指向的内存是不是已被另一个指针释放。另一方面,必须确保程序中所有使用这块内存的地方在这块内存被释放之前停止对它的使用。

内存泄漏

当动态分配的内存不再需要使用时,它应该被释放,这样它以后可以被重新分配使用。分配内存但在使用完毕后不释放将引起内存泄漏(memory leak)。在那些所有执行程序共享一个通用内存池的操作系统中,内存泄漏将一点点地榨干可用内存,最终使其一无所有。要摆脱这个困境,只有重启系统。

其他操作系统能够记住每个程序当前拥有的内存段,这样当一个程序终止时,所有分配给它但未被释放的内存都归还给内存池。但即使在这类系统中,内存泄漏仍然是一个严重的问题,因为一个持续分配却一点不释放内存的程序最终将耗尽可用的内存。此时,这个有缺陷的程序将无法继续执行下去,它的失败有可能导致当前已经完成的工作统统丢失。

http://www.yayakq.cn/news/815079/

相关文章:

  • 济南建设网站哪里好长沙网红店
  • 宝山网站建设哪家好在线html编辑器
  • 抄袭网站违法网站制作是不是要一个后台
  • 北京公司网站建设报价兰州吸引用户的网站设计
  • 南海网站制作公司宁波建站模板系统
  • 中国建设银行信用卡网站首页wordpress如何获取视频封面
  • 廊坊网站建设公司费用网页传奇新游开服
  • p图做网站兼职劳务工程信息平台
  • 现在还有人用asp做网站新一代设计协作工具
  • 福州专业做网站的公司做网站的流程
  • 个人可以建设农资网站吗建网站要花费多少钱
  • 扬州大学第四届网站建设评比微信app下载安装官方版2022网址
  • 杭州煜灿网络科技有限公司网站开发抚州招聘网站建设
  • 企业网站建设客户需求调查问卷用网站做CAN总线通信好吗
  • 福建省效能建设网站最好的网站开发工具
  • 天水 网站建设招聘h5个人网站源码
  • 潮州网站搭建找谁HTML发布网站
  • 柳州网站推广最好的公司专业建设方案
  • 西咸新区建设环保网站网站建设公司的成本有哪些内容
  • 云平台网站开发1688拿货网
  • 做市场的逛的网站调查公司做网站需要备案吗
  • 济宁网站网站建设完成网站开发需要什么样技术
  • 做网站用php西安市住房和城乡建设局官网
  • 电影网站做cpadirectory wordpress
  • 手表电商网站专业网络推广公司排名
  • 给网站做seo诊断零售管理系统哪个软件好
  • 长沙百度网站推广优化汉口网站优化
  • 杭州餐饮团购网站建设渭南网站建设远景
  • 小学生摘抄新闻安阳企业网站优化外包
  • 如何做网站关键词动态和静态网站的区别