您的位置:首页 > 编程语言 > C语言/C++

malloc、calloc、realloc以及new的区别与联系

2016-06-30 22:56 477 查看
一、定义

1、malloc函数

malloc 向系统申请分配指定size个字节的内存空间,即malloc函数用来从堆空间中申请指定的size个字节的内存大小,返回类型是
void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

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


头文件:
stdlib.h或malloc.h

功能:分配长度为num_bytes字节的内存块

与new的区别:

从本质上来说,malloc(Linux上具体实现可以参考man
malloc,glibc通过brk()&mmap()实现)是libc里面实现的一个函数,如果在source code中
没有直接或者间接include过stdlib.h,那么gcc就会报出error:‘malloc’
was not declared in this scope。如果生成了目标文件(假定动态链接malloc),
如果运行平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或者libc中没有malloc函数,那么会在运行时(Run-time)
出错。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就可以把new编译成目标代码(g++4.6.3会向目标中插
入_Znwm这个函数,另外,编译器还会根据参数的类型,插入相应的构造函数)。

2、calloc函数
函数原型:void
*calloc(size_t n, size_t size);功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。

与malloc的区别:calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
头文件:stdlib.hmalloc.h。
举例如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
char*str = NULL;
str = (char*)calloc(10,sizeof(char));/*分配内存空间*/
strcpy(str, "Hello"); /*将hello写入*/
printf("String is %s\n",str);/*显示变量内容*/
free(str);/*释放空间*/
return 0;
}
3、realloc函数

头文件:#include
<stdlib.h>
有些编译器需要#include <malloc.h>,在TC2.0中可以使用alloc.h头文件
功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,
如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来
mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。
即重新分配存储器块的地址。如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再
使用时,应使用free()函数将内存块释放。
举例1:

#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
int*pn=(int*)malloc(5*sizeof(int));
printf("malloc%p\n",pn);
for(i=0;i<5;i++)
pn[i]=i;
pn=(int*)realloc(pn,10*sizeof(int));
printf("realloc%p\n",pn);
for(i=5;i<10;i++)
pn[i]=i;
for(i=0;i<10;i++)
printf("%1d",pn[i]);
free(pn);

system("pause");
return 0;
}
运行结果如下:



举例2:

#include<malloc.h>
voidmain()
{
char*p,*q;
p=(char*)malloc(10);
q=p;
p=(char*)realloc(q,20);//A行,通过realloc扩大p的空间,并把新的地址赋值给p。
}
分析:在这段程序中我们增加了指针q,用它记录了原来的内存地址p。这段程序可以编译通过,但在执行到A行时,

如果原有内存后面没有足够空间将原有空间扩展成一个连续的新大小的话,realloc函数就会以第二种方式分配内存,
此时数据发生了移动,那么所记录的原来的内存地址q所指向的内存空间实际上已经放回到堆上了!这样就会产生q指
针的指针悬挂,即指针指向了一块没有分配给用户使用的内存,如果再用q指针进行操作就可能发生意想不到的问题。
所以在应用realloc函数是应当格外注意这种情况。

4、new关键字
“new”是C++的一个关键字,同时也是操作符。当我们使用关键字new在堆上动态创建一个对象时,它实际上做了
三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,那么第
二步会被省略。new的用法很灵活,总结两种用法如下:

 new()
分配这种类型的一个大小的内存空间,并以括号中的值来初始化这个变量;

new[]
分配这种类型的n个大小的内存空间,并用默认构造函数来初始化这些变量。

举例:

#include<iostream>
#include<cstring>
using namespace std;
int main(){

//char* p=new char("Hello");
//error分配一个char(1字节)的空间,
//用"Hello"来初始化,这明显不对
char* p=new char[6];
// p="Hello";  //不能将字符串直接赋值给该字符指针p
strcpy(p,"Hello");
cout<<*p<<endl;//只是输出p指向的字符串的第一个字符!
cout<<p<<endl; //输出p指向的字符串!
delete[] p;

system("pause");
return 0;
}
运行结果如下:



当使用new运算符定义一个多维数组变量或数组对象时,它产生一个指向数组第一个元素的指针,
返回的类型保持了除最左边维数外的所有维数。例如:

 int *p1 = new int[10];   //返回的是一个指向int的指针int*  

二、malloc、calloc、realloc以及new的区别与联系
1、前面三个函数的申明分别是:
void* realloc(void* ptr, unsigned newsize);
void* malloc(unsigned size);
void* calloc(size_t numElements, size_t sizeOfElement);
都在stdlib.h函数库内,它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL。

2、如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址。

3、free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。C++中为new/delete函数。

4、函数malloc()和函数calloc() 的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之, 如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空间还已经被重新分配)可能会出现问题。

5、malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

6、malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。

calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。

realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。

7、函数calloc() 会将所分配的内存空间中的每一位都初始化为0,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

8、realloc是从堆上分配内存的.当扩大一块内存空间时,realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;如果数据后面的字节不够,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.这句话传递的一个重要的信息就是数据可能被移动。

参考资料:
C++new的用法

malloc、calloc、realloc、new区别联系以及什么时候用(转)

malloc、calloc、realloc的区别
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++