zoukankan      html  css  js  c++  java
  • new、delete、malloc、free关系

    delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。

    malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

     free 与 delete
    1. delete 用于释放 new 分配的空间,free 用于释放 malloc 分配的空间
    2. delete [] 用于释放 new [] 分配的空间
    3. delete 释放空间的时候会调用 相应对象的析构函数
         顺便说一下new在分配空间的时候同时会调用对象的构造函数,对对象进行初始化,使用malloc则只是分配内存
    4. 调用free 之前需要检查 需要释放的指针是否为空,使用delete 释放内存则不需要检查指针是否为NULL
    5. free 和 delete 不能混用,也就是说new 分配的内存空间最好不要使用使用free 来释放,malloc 分配的空间也不要使用 delete来释放
         举个例子,<string.h>里通常有个strdup函数,它得到一个char*字符串然后返回其拷贝:
         char * strdup(const char *ps); // 返回ps所指的拷贝
         在有些地方,c和c++用的是同一个strdup版本,所以函数内部是用malloc分配内存。这样的话,一些不知情的c++程序员会在调用strdup后忽视了必须对   strdup返回的指针进行free操作。为了防止这一情况,有些地方会专门为c++重写strdup,并在函数内部调用了new,这就要求其调用者记得最后delete。你可以想象,这会导致多么严重的移植性问题,因为代码中strdup以不同的形式在不同的地方之间颠来倒去。
     
    补充一个问题,free和delete 是如何知道需要释放的内存块的大小的?
         
         在调用malloc或new 分配内存空间的时候,实际分配的空间会比程序员申请的空间要大。实际分配的内存空间前面有一部分空间用于保存所分配内存的大小,校验和等信息。当分配函数返回时,将会返回实际可操作的地址(也就是实际分配空间加上前面用于记录分配信息的空间之后的地址)。下面举个例子,例子通过破坏 new 返回地址的前面四个字节的数据导致内存空间释放出问题。如果不破坏前面的数据则不会出现内存不能释放的情况。
     1 #include <stdio.h>
     2 #include <new>
     3 #include <iostream>
     4 #include <stdlib.h>
     5 #include <string.h>
     6 
     7 int main()
     8 {
     9     int *p = NULL,*p1=NULL;
    10     int i;
    11     //p = (int *) malloc(10 * sizeof(int));
    12     p = new int[10];
    13 
    14     memset(p,0,sizeof(int) * 10);
    15     for(i=0;i<10;i++)
    16         printf("P:%d\t",p[i]);
    17     printf("addr p: %x\n",p);
    18 
    19     *(p-1) = 2; //如果不注释掉这一行则程序运行不正确
    20     *(p+11) = 3;
    21     printf("addr before p: %x\n",p+11);
    22     printf("%x %x\n",*(p-1),*(p+11));
    23 
    24     //free(p);
    25     delete [] p;
    26     printf("free successfully! \n");
    27     return 0;
    28 }

    当注释了*(p-1) = 2之后运行结果为:

    当不注释*(p-1) =2 这一行时,结果为:


     
     
  • 相关阅读:
    [CF1336C] Kaavi and Magic Spell
    [CF1338C] Perfect Triples
    [CF1353F] Decreasing Heights
    [CF1442B] Identify the Operations
    [CF1354E] Graph Coloring
    [CF1364D] Ehab's Last Corollary
    php-fpm和fastcgi的区别
    phpredis实现互斥锁
    关于lnmp情况下PHP单线程的理解
    客户端断开链接以后 PHP执行过程实测
  • 原文地址:https://www.cnblogs.com/shed/p/2747202.html
Copyright © 2011-2022 走看看