new/malloc的差别

1. malloc()函数

1.1 malloc的全称是memory allocation。中文叫动态内存分配。

原型:extern void *malloc(unsigned int num_bytes);

说明:分配长度为num_bytes字节的内存块。假设分配成功则返回指向被分配内存的指针。分配失败返回空指针NULL

当内存不再使用时,应使用free()函数将内存块释放。

1.2 void *malloc(int size);

说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型能够强制转换为不论什么其他类型的指针。   

备注:void* 表示未确定类型的指针。更明白的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比方是char还是int或者...)

1.3 free

void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它又一次得到自由。

为什么free 函数不象malloc 函数那样复杂呢?这是由于指针p 的类型以及它所指的内存的容量事先都是知道的。语句free(p)能正确地释放内存。假设p 是NULL 指针。那么free

对p 不管操作多少次都不会出问题。假设p 不是NULL 指针,那么free 对p连续操作两次就会导致程序执行错误。

1.4注意事项

1)申请了内存空间后,必须检查是否分配成功

2)当不须要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。

3)这两个函数应该是配对。假设申请后不释放就是内存泄露;假设无故释放那就是什么也没有做。释放仅仅能一次。假设释放两次及两次以上会出现错误(释放空指针例外,释放空指针事实上也等于啥也没做。所以释放空指针释放多少次都没有问题)。

4)尽管malloc()函数的类型是(void *),不论什么类型的指针都能够转换成(void *),可是不妨在前面进行强制类型转换。由于这样能够躲过一些编译器的检查。

1.5  malloc()究竟从哪里得到了内存空间?

答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空暇内存地址的链表。当操作系统收到程序的申请时。就会遍历该链表。然后就寻找第一个空间大于所申请空间的堆结点。然后就将该结点从空暇结点链表中删除,并将该结点的空间分配给程序。

2. new运算符

2.1 C++中,用new和delete动态创建和释放数组或单个对象

动态创建对象时,仅仅需指定其数据类型,而不必为该对象命名,new表达式返回指向该新创建对象的指针,我们能够通过指针来訪问此对象

int *pi=new int;

这个new表达式在堆区中分配创建了一个整型对象,并返回此对象的地址,并用该地址初始化指针pi 。

2.2 动态创建对象的初始化

动态创建的对象能够用初始化变量的方式初始化。

int *pi=new int(100); //指针pi所指向的对象初始化为100

string *ps=new string(10,’9’);//*ps 为“9999999999”

假设不提供显示初始化,对于类类型,用该类的默认构造函数初始化。而内置类型的对象则无初始化

也能够对动态创建的对象做值初始化:

int *pi=new int( );//初始化为0

int *pi=new int;//pi 指向一个没有初始化的int

string *ps=new string( );//初始化为空字符串 (对于提供了默认构造函数的类类型,没有必要对其对象进行值初始化)

2.3 撤销动态创建的对象

delete表达式释放指针指向的地址空间。

delete pi ;// 释放单个对象

delete [ ]pi;//释放数组

假设指针指向的不是new分配的内存地址。则使用delete是不合法的。

2.4 在delete之后,重设指针的值

delete p; //运行完该语句后。p变成了不确定的指针,在非常多机器上,虽然p值没有明白定义。但仍然存放了它之前所指对象的地址。然后p所指向的内存已经被释放了。所以p不再有效。此时,该指针变成了悬垂指针(悬垂指针指向以前存放对象的内存,但该对象已经不存在了)。

悬垂指针往往导致程序错误,并且非常难检測出来。

一旦删除了指针所指的对象,马上将指针置为0,这样就很清楚的指明指针不再指向不论什么对象。(零值指针:int *ip=0;)

2.5 区分零值指针和NULL指针

零值指针。是值是0的指针,能够是不论什么一种指针类型,能够是通用变体类型void*也能够是char*。int*等等。

空指针,事实上空指针仅仅是一种编程概念,就如一个容器可能有空和非空两种基本状态。而在非空时可能里面存储了一个数值是0,因此空指针是人为觉得的指针不提供不论什么地址讯息。參考:http://www.cnblogs.com/fly1988happy/archive/2012/04/16/2452021.html

2.6 new分配失败时。返回什么?

1993年前,c++一直要求在内存分配失败时operator   new要返回0。如今则是要求operator   new抛出std::bad_alloc异常。非常多c++程序是在编译器開始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代码,所以他们提供了另外形式的operator   new(以及operator   new[])以继续提供返回0功能。这些形式被称为“无抛出”,由于他们没用过一个throw,而是在使用new的入口点採用了nothrow对象:

class   widget   {   ...   };

widget   *pw1   =   new   widget;//   分配失败抛出std::bad_alloc

if   (pw1   ==   0)   ... //   这个检查一定失败

widget   *pw2   =   new   (nothrow)   widget;   //   若分配失败返回0

if   (pw2   ==   0)   ... //   这个检查可能会成功

3. malloc和new的差别

3.1 new 返回指定类型的指针。而且能够自己主动计算所须要大小。

比方:   

1) int *p;   

p = new int; //返回类型为int* 类型(整数型指针)。分配大小为 sizeof(int);   

或:   

int* parr;   

parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;   

2) 而 malloc 则必需要由我们计算字节数,而且在返回后强行转换为实际类型的指针。   

int* p;   

p = (int *) malloc (sizeof(int)*128);//分配128个(可依据实际须要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中

double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中

3.2 malloc 仅仅管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的

除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其他操作上保持一致。

4.有了malloc/free为什么还要new/delete?

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

它们都可用于申请动态内存和释放内存。

2) 对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同一时候要自己主动运行构造函数,对象在消亡之前要自己主动运行析构函数。

因为malloc/free是库函数而不是运算符,不在编译器控制权限之内,不可以把运行构造函数和析构函数的任务强加于malloc/free。

因此C++语言须要一个能完毕动态内存分配和初始化工作的运算符new,以及一个能完毕清理与释放内存工作的运算符delete。注意new/delete不是库函数。

我们不要企图用malloc/free来完毕动态对象的内存管理。应该用new/delete。

因为内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。

3) 既然new/delete的功能全然覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?这是由于C++程序常常要调用C函数,而C程序仅仅能用malloc/free管理动态内存。

假设用free释放“new创建的动态对象”。那么该对象因无法运行析构函数而可能导致程序出错。

假设用delete释放“malloc申请的动态内存”,结果也会导致程序出错,可是该程序的可读性非常差。

所以new/delete必须配对使用。malloc/free也一样。

new/delete在C++中能够重载

时间: 2024-10-13 04:28:09

new/malloc的差别的相关文章

C++ - new与malloc的差别

malloc是C++语言的标准库函数:而new是C++语言中的操作符. new返回指定类型的指针,而且能够自己主动计算所需空间的大小:而malloc必需要由用户自己计算所需空间大小,并在返回后强行转换为实际类型的指针. malloc仅仅管内存分配,不能对所得的内存进行初始化,其所获内存空间中上的值是随机的:而new除了分配内存处,还会对对象做初始化.

C++之new和malloc差别

在C++程序猿面试中.非常easy被问到new 和 malloc的差别.偶尔在quora上逛.看到Robert Love的总结.才发现自己仅仅知道里面的一两项就沾沾自喜,从来没有像这位大牛一样去细致思考这些问题,借着这篇文章细致探讨下这个经典问题. 一.new是操作符.而malloc是函数 void* malloc(size_t); void free(void*); void *operator new (size_t); void operator delete (void *); void

【C语言天天练(九)】动态内存分配

引言:数组的元素存储于内存中连续的位置上.当一个数组被声明时.它所须要的内存在编译时就被分配. 可是,我们能够使用动态内存分配在执行时为它分配内存. 一块内存的生命周期能够分为四个阶段:分配.初始化.使用.释放. 内存的分配一般使用C函数库里的malloc函数(原型:void *malloc(size_t size)). 关于malloc函数应该注意一下几点: 1.malloc的參数就是须要分配的内存的字节数. 2.malloc所分配的是一块连续的内存. 3.分配成功.则返回指向分配内存起始地址

malloc()与calloc差别

Both the malloc() and the calloc() functions are used to allocate dynamic memory. Each operates slightly different from the other. Both the malloc() and the calloc() functions are used to allocate dynamic memory. Each operates slightly different from

malloc、calloc、realloc三者的差别

1.malloc 作用:分配内存块 原型:void *malloc(size_t size);size表示要分配的字节数 返回值:返回一个指向所分配空间的void指针,假设没有足够的内存可用,则返回NULL. 假设要返回一个指向特定类型的指针,则在返回值上用一个类型转换.比如: char* p; p=(char*)malloc(20); 假设size是0,则malloc在堆中分配一个长度为0的项,而且返回一个指向那项的有效指针.比如: int *p1=(int*)malloc(0) //ok,p

多进程与多线程差别

 在Unix上编程採用多线程还是多进程的争执由来已久,这样的争执最常见到在C/S通讯中服务端并发技术 的选型上,比方WEBserver技术中.Apache是採用多进程的(perfork模式,每客户连接相应一个进程,每进程中仅仅存在唯一一个运行线程), Java的Web容器Tomcat.Websphere等都是多线程的(每客户连接相应一个线程,全部线程都在一个进程中). 从Unix发展历史看,伴随着Unix的诞生进程就出现了.而线程非常晚才被系统支持,比如Linux直到内核2.6.才支持符合P

char* 和char[]的差别

下面内容均来自互联网,系笔者汇总并总结. 1. 问题介绍 问题引入: 在实习过程中发现了一个曾经一直默认的错误,相同char *c = "abc"和char c[]="abc",前者改变其内 容程序是会崩溃的,而后者全然正确. 程序演示: 測试环境Devc++ 代码 #include <iostream> using namespace std; main() { char *c1 = "abc"; char c2[] = "

堆和栈的差别(转过无数次的文章)

一.预备知识—程序的内存分配    一个由C/C++编译的程序占用的内存分为下面几个部分    1.栈区(stack)—   由编译器自己主动分配释放   ,存放函数的參数值,局部变量的值等.其    操作方式相似于数据结构中的栈.    2.堆区(heap)   —   一般由程序猿分配释放,   若程序猿不释放,程序结束时可能由OS回    收   .注意它与数据结构中的堆是两回事,分配方式倒是相似于链表,呵呵.    3.全局区(静态区)(static)—,全局变量和静态变量的存储是放在一

Linux程序存储结构与进程结构 堆和栈的差别

摘要:本文主要讲述了Linux系统中.程序存储结构(代码区.数据段和BBS区)与进程的基本结构(代码区.数据段.BBS区.堆和栈).以及堆和栈的差别. Linux程序存储结构与进程结构 1.Linux程序存储结构 在Linux系统下,程序是一个普通的可运行文件,图1是一个Linux下ELF格式可运行文件的基本情况. 图1 ELF格式可运行文件的基本信息 能够看出,此ELF格式可运行文件在存储时,没有调入到内存,分为代码区(text),数据区(data)和为初始化区(bss)3个部分.各段基本说明