关于new,delete,malloc,free的一些总结

news/2024/7/20 13:17:21 标签: 操作系统, 内存管理, c/c++

 

  • 首先,new,delete都是c++的关键字并不是函数,通过特定的语法组成表达式,new可以在编译的时候确定其返回值.可以直接使用string *p=new string("asdfgh");来直接赋值。这其中在调用new分配空间得时候的时候,系统其实直接调用了类或结构的构造函数来对对其进行赋值,这个过程就相当于是string p=string("asdfgh"); 或者string p("asdfgh");(其实上面的过程还是有一定的不同之处;一 个显示式调用,一个隐式调用,两者都是在进程虚拟地址空间中的栈中分配内存,而第一种使用了new,在堆中分配了内存,而栈中内存的分配和释放是由系统管 理,而堆中内存的分配和释放必须由程序员手动释放,所以这就产生一个问题是把对象放在栈中还是放在堆中的问题,这个问题又和堆和栈本身的区别有关)    对于类和结构体这样子很方便,对一般的数据类型这样就没什么必要了。  在对这样子的分配空间进行内存释放的时候直接调用delete来释放,delete p就可以了。这个过程中,对于一般数据类型就直接释放,对于类或者结构体delete调用其析构函数类释放内存。
  • 用new来分配多块内存的时候就要使用new[]来分配,eg:char* p=new char[size];string *p=new string [size];在这个过程中new[]干了两件事,一个是记录要分配的数量size,(可以是在分配的内存前一段某个位置额外分配分配了几个字节来说储存数据来记录大小,也可以是在后台专门有一个表来记录各个数组的大小,这与内存分配器的工作方式有关。你可以以n种方式来实现这个过程,但是必须要能记录数组的大小)再向系统申请分配内存并返回数组的指针(而不是所有分配的空间的起始地址)。对于结构体或者类,new[]调用构造函数size次,其实质还是记录大小和分配空间两件事。对于用new[]分配的内存在释放的时候就必须用delete[]来释放,直接delete[] p就可以了。delete[]怎么知道要释放多大的内存或调用多少次析构函数,就是由于在new分配的时候专门特意的记录了要分配数组的大小,delete[]的时候就先读取这个值,然后调用size次析构函数来释放空间或者根据size来直接释放空间。
  • void *operator new(size_t);     //allocate an object
    void *operator delete(void *);    //free an object
    
    void *operator new[](size_t);     //allocate an array
    void *operator delete[](void *);    //free an array
    

    这是在c++11 new中对这几个函数的定义,平时可直接使用,但再次主意new[]分配的只能通过delete[]来释放,如果用delete的话这只能释放掉数组的第一项,后边的还是存在的。因为数组的地址就是数组第一项的地址。所以new[]的一定要用delete[]来释放。

  •                                                    
  • malloc与free都是c语言中的函数,malloc的返回值为void型,在使用的时候要注意对其进行类型转换,                               eg:char* p=(char*)malloc(number*sizeof(char));malloc在分配内存的时候是以字节来分配的。在分配之前也会记录数组的大小和类型。最后返回一个指向数据区的void型指针。malloc分配的内存必须通过free来释放。与malloc有关的函数还有calloc与realloc,其中calloc在分配完内存返回指针之前把所有的数据都初始化为0,相当于malloc加上memset。realloc函数可以吧原来分配的好的内存块的改变大小。动态分配的内存必须是整体一块释放,但是realloc可以缩小一小块动态分配的内存,有效的释放他尾部的部分内存。
  • 关于在调用delete或者free之后系统是否真正的释放了内存的问题。可以通过程序+任务管理器性能窗口来进行检测
    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    char*ch[1000];
    int size = 20000;
    int main()
    {
    	int i, j;
    	for (int i = 0; i < 1000; i++)
    	 ch[i] = (char*)malloc(sizeof(char)*size);
    	for (i = 0; i < 1000;i++)//换入内存,如不进行操作,glibc并不会真正的向系统申请内存
    		for (j = 0; i < size; j++)
    			ch[i][j] = ' '; 
    		Sleep(20000);//在此期间查看内存使用情况
    		for (i = 0; i < 1000; i++)
    			free(ch[i]);
    		Sleep(20000);//再次查看内存使用情况
    	return 0;
    }
    

     实验发现,free前与free后的内存使用情况是相同,并没有因为free而空闲出很多内存。而当程序跑完最后的return 0;之后内存使用率才真正的降下来。此时程序涉及到的内存才真正的被完全释放。所以答案是free并没有真正释放内存,相关内存块储存的东西仍然在,而free与delete的过程只是切断了指针与内存块的联系,这块内存本身在没有其他的数据对其进行修改的时候一直都储存着其原来的东西。有其他的内存分配需求的时候这块内存很可能就被分配过去了,然后谁想怎么改就怎么改(就类似于优盘格式化后不向里边写入新东西,原来的东西还是存在的一样)(如果分配到的内存特别特别大的话,free后有可能内存使用率直接降下来,这与操作系统内存管理有关)

  • warning:      1.不管是用new还是用malloc在进行内存分配的时候都要先检查一下是否分配到内存,分配完了之后要赶紧检查一下返回指针是否为NULL;不管是用free还是用delete或者delete[]释放完内存之后都要把原本来指针变为空指针,要不然就变成野指针了,很危险。 2.一个new对应一个delete,一个new[]对应一个delete[],一个malloc对应一个free,必须这样子。要不然会造化内存泄露。也不要对直接定义了的变量或者数组进行free或者delete;不能free一个非malloc返回的指针,不能delete一个非new返回的指针。

转载于:https://www.cnblogs.com/freedom314/p/5027896.html


http://www.niftyadmin.cn/n/1316226.html

相关文章

新项目又要开始

这次任务有点重&#xff0c;这条路还很长。时间都去哪了&#xff1f;转载于:https://www.cnblogs.com/wangzhe688/p/5029627.html

夺命雷公狗---javascript NO:17 默认行为2

解决兼容性问题 ① 在public.js中创建prevent函数 ② 判断浏览器类型 ③ 编写一下程序代码 //解决阻止默认行为兼容性问题 function prevent(event){if(window.event){//IE模型浏览器window.event.returnValue false;}else{//w3cevent.preventDefault();} } ④ 在html页面测试…

夺命雷公狗---Smarty NO:04 设计篇2 变量调节器

变量调节器主要是对变量进行格式化。 基本格式 {$变量名称|调节器:参数1:参数2:……} 常用的变量调节器&#xff1a; {$var|capitalize} &#xff1a;首字母大写 {$var|count_characters:true} &#xff1a;计算字符数&#xff0c;如果参数为true&#xff0c;则计算空格 {$var|…

对抗警报疲劳的七个步骤!

警报疲劳是一个棘手的问题&#xff0c;但事不宜迟&#xff0c;越早开始越好。利用警报数据&#xff0c;你可以有效清理监控系统&#xff0c;排除不可操作的警报。 简便起见&#xff0c;我们编写了对抗警报疲劳的七个步骤。 减少警报疲劳的七个步骤 1.付诸行动 清理监控系统并不…

Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager

1、错误叙述性说明 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help | start | stop } 2014-7-12 14:54:49 org.apache.catalina.core.AprLifecycleListener init 信息: Loaded APR based Apache Tomcat Native library 1.1.…

JQuery validate.js 在ajax提交form时如何触发

在使用jquery validate.js 插件时&#xff0c;发现&#xff0c;如果是用onclick事件捕获提交按钮的动作&#xff0c;并且ajax动态提交form&#xff0c;验证不会被触发&#xff0c;而是直接提交了form。 后来发现&#xff0c;需要手动调用该form的validate方法&#xff0c;就可以…

通过python构建集中式的病毒扫描机制

Clam AntiVirus(Clam AV)是一个免费而且开放源码的防毒软件&#xff0c;软件与病毒库的更新由开源社区免费发布&#xff0c;目前ClamdAV主要为Linux、Uinux系统提供病毒扫描查杀pyClamad是一个python的第三方模块&#xff0c;可让python直接使用ClamAV病毒扫描守护进程clamd来实…

【转】 Pro Android学习笔记(八六):了解Package(5):使用lib

目录(?)[-] 在项目中使用lib源代码了解一些机制文章转载只能用于非商业性质&#xff0c;且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处&#xff1a;http://blog.csdn.net/flowingflying/ 在上一次学习中&#xff0c;我们创建的lib项目TestLib&#xff0c;本次学习…