zoukankan      html  css  js  c++  java
  • new与delete,malloc与free

    1.new_delete与malloc_free

        malloc/free:

              malloc原型: void *malloc(long NumBytes)

                   该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。申请了内存空间后,必须检查是否分配成功。

              free原型:void free(void *FirstByte):

                  该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。

     

        二者区别在于

            ⑴ malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符

            ⑵ new能够自动分配空间大小,malloc需要计算大小作为传入参数。但是,2者都是从堆中获得内存。

            new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。实际上,malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。而new 内置了sizeof、类型转换和类型安全检查功能。对于非内部数据类型的对象而言,new 在创建动态对象的同时完成了初始化工作。

            内存分配失败,处理机制不同。

               malloc分配失败时,返回NULL。因此必须要人工检查是否分配成功

                new分配失败时,抛出std::bad_alloc异常。可以在new的入口点采用了nothrow对象避免跑出而返回0:

       class widget   {   ...   };
       widget *pw1=new  widget;//分配失败抛出std::bad_alloc  
       if(pw1== 0)   ... //   这个检查一定失败
       widget* pw2= new (nothrow)   widget;//若分配失败返回0
       if(pw2==0) ... //这个检查可能会成功

        

       ❸new和malloc的用法:

    int *p = (int *) malloc(sizeof(int) * length); 
    
    Obj *objects = new Obj[100](1);// 创建100 个动态对象的同时赋初值1
    string *ps=new string(10,’9’);//*ps 为“9999999999”
    int *pi=new int(100); //指针pi所指向的对象初始化为100

    2.realloc重新分配内存机制

          extern void *realloc(void *mem_address, unsigned int newsize)//注意newsize并非是需要增加相对的大小,而是总的大小

        原理

             先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

            如果重新分配成功则返回指向被分配内存指针否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。也需要人工检查是否分配失败。

       例如:

             对于一个2*4的数组,要扩容至为3*5的数组。

    #include<iostream>
    using namespace std;
    
    //数组显示
    void show(int p[],int n){
    	for(int i=0;i<n;i++)
    		cout<<p[i]<<"  ";
    	cout<<endl;
    }
    void main(){
    
    	//初始大小2*4
    	int** p=new int*[2];
    	p[0]=new int[4];
    	p[1]=new int[4];
    	for(int i=0;i<4;i++){
    		p[0][i]=i;
    		p[1][i]=i+4;
    	}
    	show(p[0],4);show(p[1],4);
    
    	//重新分配,扩容至3*5
    	p=(int**)realloc(p,3*sizeof(int*));
    	p[0]=(int*)realloc(p[0],5*sizeof(int));
    	p[1]=(int*)realloc(p[1],5*sizeof(int));
    	p[2]=(int*)malloc(5*sizeof(int));
    
    	//数组赋值
    	if(!p&&!p[0]&&!p[1]&&!p[2]){
    		p[0][4]=8;
            	p[1][4]=9;
    
    	       for(int i=0;i<5;i++)
    		     p[2][i]=i+10;
    	}
    
    	show(p[0],5);show(p[1],5);show(p[2],5);
    
    
    	for(int i=0;i<3;i++)
    		delete[]p[i];
    	delete []p;
    }



    参考:

       1.new和malloc的区别

                    

  • 相关阅读:
    十二、redis常用的运维命令及注意参数
    十一,redis的主从集群
    十、redis的持久化配置
    九、Redis的消息发布和订阅
    八、Redis 中的事务
    apache、nginx、iis日志记录的各个字段内容与含义
    Pikachu-RCE
    Pikachu-SQL-Inject(SQL注入漏洞)
    Pikachu-CSRF(跨站请求伪造)
    Pikachu-XSS(跨站脚本)漏洞
  • 原文地址:https://www.cnblogs.com/engineerLF/p/5393035.html
Copyright © 2011-2022 走看看