Effective C++(Item3) Prefer new and delete to malloc and free

 

string* stringArray1 = static_cast<string*>(malloc(10*sizeof(string)));

string* stringArray2 = new string[10];

stringArray1 points to enough memory for 10 string objects,but no objects have been constructed in that memory,and you have no way to initialize the objects in the array;

stringArray2 points to an array of fully constructed string objects,each of whick can safely be used in any operation taking a string;

free(stringArray1);

delete [] stringArray2;

the call to free will release the memory pointed to by stringArray1,but no destructor will be called on the strong objects in that memory,if the string objects themselves allocated memory,as string objects are wont to all the memory they allocated will be lost

delete is called on stringArray2,a destructor is called for each object in array before any memory is released.

Mixing new and delete with malloc and free is usually a bad idea;

Malloc and free

Malloc: 向系统申请分配指定size个字节的内存空间。

返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针

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

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

返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

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

函数的工作机制:

malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断

New and Delete

(1)new 可用来生成动态无名变量
int *p = new int;
int *p = new int[10];

int* p1;
double * p2;
p1 = new int(12);(1)
p2 = new double[100];(2)

NOTICE:
(1)表示动态分配了用于存放整型数据的内存空间,将初始12写如该内存空间,并将首地址值返回给p1;
(2)动态分配了具有100个双精度实型数组元素的数组,同时将个存储区的首地址的值返回给p2
  对于生成二维及更高维的数组,应使用多维指针。
  以二维指针为例
  int **p=new int* [row]; //row是二维数组的行,p是指向一个指针数组的指针
  for(int i=0; i<row; i++)
  p[i]=new int [col]; //col是二维数组的列,p是指向一个int数组的指针
  删除这个二维数组
  for(int i = 0; i < row; i++)
  delete []p[i]; //先删除二维数组的列
  delete []p;
  使用完动态无名变量后应该及时释放,要用到 delete 运算符
  delete p; //释放单个变量
  delete [ ] p;//释放数组变量(不论数组是几维)

new的过程
 当我们使用关键字new在堆上动态创建一个对象时,
它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。
当然,如果我们创建的是简单类型的变量,那么第二步会被省略。
假如我们定义了如下一个类A:
  class A
  {
  int i;
  public:
  A(int _i) :i(_i*_i) {}
  void Say() { printf("i=%dn", i); }
  };
  //调用new:
  A* pa = new A(3);
  那么上述动态创建一个对象的过程大致相当于以下三句话(只是大致上):
  A* pa = (A*)malloc(sizeof(A));
  pa->A::A(3);
  return pa;
  虽然从效果上看,这三句话也得到了一个有效的指向堆上的A对象的指针pa,
    但区别在于,当malloc失败时,它不会调用分配内存失败处理程序new_handler,而使用new的话会的

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值