精华内容
下载资源
问答
  • 关于newdelete和堆的一些理解 先看以下的两个简单的程序: 第一: //////////Visula C++ 6.0环境 #include<iostream.h> void main() { int a=3; int *p=new int; p=&a; cout<<*p<<endl; ...
    关于new、delete和堆的一些理解
    先看以下的两个简单的程序:

    第一:
    //Visula C++ 6.0环境
    #include<iostream.h>

    void main()
    {
    int a=3;
    int *p=new int;
    p=&a;

    cout<<*p<<endl;
    delete p; /有错误
    }


    第二:
    //Visual C++ 6.0环境

    #include<iostream.h>

    void main()
    {
    int a=3;
    int *p=new int;
    *p=a;

    cout<<*p<<endl;
    delete p;
    }


    其中第一个程序存在错误(会生成.exe文件,但是运行有错误)
    问题出在对new和delete、堆不是很了解。
    而第二个程序是正确的。
    现在我来分析一下:
    int *p=new int;
    是在heap分配一个int型的空间,而p是在stack里的一个指针,它指向heap里的那个int,
    在程序结束的时候,p指针将释放掉,所以要在程序结束的时候delete p,这是为了释放在
    heap里分配的那个int,否者会造成heap区空间的泄漏,这是很严重的。

    第一个程序中的:
    p=&a;
    它把a的地址赋给p,这时p指的是a,而不是heap里的那个int了,后来
    delete p;
    这是想删除p指向的内容,但是此时p指向的stack里的a了,而delete是不能用
    于stack的数据的,所以出现了错误。

    第二个程序中的:

    *p=a;
    这只是将a的值赋给p指向的那个int,此时p还是指向heap里的int,
    所以这里的
    delete p;
    是合法的了,不会出现错误。

    转载于:https://www.cnblogs.com/super119/archive/2011/04/10/2011339.html

    展开全文
  • 以下是书上的范例,我疑惑的是明明声明了两个指针,pnname,为什么函数用完后只delete name,而没有delete pn。照理说动态变量不是不会再函数执行完之后被释放的吗? #include #include // or string.h using ...
    以下是书上的范例,我疑惑的是明明声明了两个指针,pn和name,为什么函数用完后只delete name,而没有delete pn。照理说动态变量不是不会再函数执行完之后被释放的吗?
    

    #include
    #include // or string.h
    using namespace std;
    char * getname(void); // function prototype
    int main()
    {
    char * name; // create pointer but no storage
    name = getname(); // assign address of string to name
    cout << name << " at " << (int *) name << “\n”;
    delete [] name; // memory freed
    name = getname(); // reuse freed memory
    cout << name << " at " << (int *) name << “\n”;
    delete [] name; // memory freed again
    return 0;
    }
    char * getname() // return pointer to new string
    {
    char temp[80]; // temporary storage
    cout << "Enter last name: ";
    cin >> temp;
    char * pn = new char[strlen(temp) + 1];
    strcpy(pn, temp); // copy string into smaller space
    return pn; // temp lost when function ends
    }
    回答:
    你只new了一次,然后pn指针的值被返回,变成了name 这样name和pn就是等价的,name就是pn所以释放name就是释放了pn。getname返回的似乎pn的值,即是new所分配的地址开始值,然后将这个值放到name里,name就变成了指向这块内存的指针了,如果释放这块内存的话用delete name即可。为什么不释放pn,因为指针是局部变量,delete pn会清除函数要返回的结果。
    其实是更本质的东西,指针的意思是,声明一个局部自动变量,其中存储的是一块区域开始的地址值,并赋予这个局部变量不同的编译类型,在编译时,不仅仅将这个变量当做操作对象,同时也将其内容当做操作对象。所以new和delete所操作的是这个变量的内容所指向的内存和pn和name都没关系。pn和name 如果没指向任何内存,那么他们就是一普通自动变量,超出作用于就会被销毁。内存泄露的原因就是,类似pn和name的变量被自动销毁,而他们所指向的内存区域,我们永远不知道在哪里了,就跟你的电脑的快捷方式似的,你删除了快捷方式,游戏还是在的,如果你没办法访问他安装的地方,你就玩不了了。

    **注意:**释放pn指向的内存,不会删除指针pn本身,也就是我们可以将pn重新指向另一个新分配的内存块. 一定要配对的使用new和delete,否则将会发生内存泄漏(memory leak), 也就是说被分配的内存再也无法使用了, 如果内存泄漏严重, 程序将因为分配不到新内存而终止.
    
    展开全文
  • 在C++中,申请堆内存,使用new或者new[],在回收用 ...关于 new[] delete[],其中又分为两种情况:(1) 为基本数据类型分配回收空间;(2) 为自定义类型分配回收空间。 先看以下例子: #include #include using
    在C++中,申请堆内存,使用new或者new[],在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
    

    关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。

    先看以下例子:

    #include<iostream>
    #include<new>
    
    using namespace std;
    
    int main()
    {
    	//new int []
    	int b[]={1,2,3,4};
    
    	int *c=new int [10];
    
    	memset(c,0,10*sizeof(int));
    
    	memcpy(c,b,10*sizeof(int));
    
    	for(int i=0;i<4;i++)
    	{
    		cout<<*(c+i)<<" ";
    	}
    	cout<<endl;
    
    	delete [] c;//这时候delete c是没有区别的
    
    	char *str=new char;
    
    	char s='a';
    
    	*str=s;    //给堆内存赋值 类似于上面的memcpy函数的功能
    	//str=&s;  //让指针指向桟内存,错误的做法
    
    	cout<<*str<<endl;
    
    	delete str;//这时候delete []str是没有区别的
    
    	system("pause");
    	return 0;
    }

    可以正常运行,在内置的类型中,比如int,char,long等delete 和 delte[]是没有区别的,但是如果是自定义的结构或类,则不会回收,就会造成内存泄露。


    再看第二种情况:

    #include <iostream>
    #include<new>
    
    using namespace std;
    
    class T 
    {
    public:
    
      T() { cout << "constructor" << endl; }
    
      ~T() { cout << "destructor" << endl; }
    };
    
    int main()
    {
      const int NUM = 3;
    
      T* p1 = new T[NUM];
    
      cout<<p1<<endl;
    
      delete [] p1;
    
      //delete [] p1;
    
      T* p2 = new T[NUM];
    
      cout<<p2<<endl;
    
      delete [] p2;
    
      system("pause");
      return 0;
    }

    运行结果:


    结果分析:

    从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如 p1[1]、p1[2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用 delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。 
        基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。 
        所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用

    展开全文
  • new和malloc都是常用的申请动态内存方式。他们有以下区别: 1、malloc / free 是C语言的标准库函数,new/delete是c++的运算符(或者说关键字); 2、new/delete比malloc/free更智能,在申请和释放内存时会自动调用...

    new和malloc都是常用的申请动态内存方式。他们有以下区别:

    1、malloc / free 是C语言的标准库函数,new/delete是c++的运算符(或者说关键字);

    2、new/delete比malloc/free更智能,在申请和释放内存时会自动调用对象的构造函数和析构函数(其底层仍靠malloc/free来实现),malloc则只管分配内存并不对所得的内存初始化;

    3、返回类型不同,new返回的是指定类型的指针,且自动计算所需内存的大小,malloc返回的是 void* 型,需要手动进行数据类型转换,且内存大小需要手动计算;

    如:

    int *pint_n = new int[10];//返回类型为 int* 型,申请内存大小为 sizeof(int)*10;

    int *pint_m = (int *)malloc(10 * sizeof(int)); //返回的是 void* 型,需手动强转为 int* 型

    4、如果申请内存失败,表现形式不同,malloc申请内存失败后返回空指针NULL,new申请失败则抛出异常,直接比较指针是否为空是没有意义的,需要用try、catch的方式捕获异常;

     

    5、处理数组的方式不一样,C++提供了new[],delete[],可以通过构造函数和析构函数来逐个处理数组元素,malloc和free则不区分数组还是普通对象,更为佛系。

    注意

    int *p = NULL;
    
    try {
    
            p = new int [10];
        
        }
            catch(bad_alloc& a)
        {
            cout<<a.what()<<endl;
        }
        
        delete[] p;
        p = NULL;
    
        int *q = (int *)malloc(10 * sizeof(int));
    
        free( q );
        q = NULL;
    

    执行delete删除指针执向的内存后,p变成了不确定指针(悬垂指针),这很容易导致程序运行错误,需要手动指定其值为NULL;

    不管使用new还是malloc申请的动态内存,千万不要忘记最后使用对应的delete或free手动释放内存,要不然很容易造成内存溢出,造成不必要的严重后果。

    具体分析如下:

    malloc(),malloc是从C语言那里继承过来的一个函数,其用于分配一片内存,它的返回结果是一个指向你所需求的内存的指针,其函数原型和使用例子如下:

    /*
    
      函数原型
    
      其中__size是你要分配的大小,其单位是byte
    
    */
    
    void* malloc(size_t __size);
    
    // 用例
    
    int* pInt = (int*) malloc(sizeof(int));              // 分配了一个int
    
    double* pDoubleArray = (double*) malloc(sizeof(double) * 5);   // 分配了一个double数组,其大小为5

    一般来说,malloc总是能分配出内存。但是也存在山穷水尽,内存不够用的情况。这时候malloc会返回一个空指针(NULL, nullptr)。当使用malloc的时候,最好每次都要判断一下返回的指针是否为空。

    已经分配了内存后,当程序运行到某一些时刻,又不想要这些内存了。这时候就要手动释放内存,否则的话就会造成内存泄露。通过free() 函数来释放内存,其函数原型和使用例子如下:

    // 原型
    
    void free(void* __ptr);
    
    
    
    // 用例
    
    free(pInt);
    
    free(pDoubleArray);

    而传给free函数的只是一个指针,不管是分配了一个元素还是分配了一个数组,free总能释放掉这些内存(free 怎么知道你分配的数组的大小?)

    接下来说说malloc在分配内存的时候干了什么。
    malloc在分配内存的时候,不仅仅会分配你需要的内存大小,它还会在你的内存的头部和尾部加上一些额外的信息(俗称cookie)。

    比如说用来DEBUG的信息和你的内存的大小。这就解释了为什么能free掉你的内存,因为它知道你这块内存是多大的。值得一提的是这些Cookie会占用一些内存。

    还有一点是malloc只是一个第三方的函数,并不是操作系统的内核函数。如果有额外的需求的话,可以设计自己的malloc。

    接下来谈谈new:

    new是c++提供的一个操纵符(或者说关键字)。其也是用于分配内存的。其用法例如:

    int* pInt = new int(3);           //分配并构造一个int
    
    double* pDoubleArray = new double[5];   //分配了一个double数组,其大小是5
    
    
    
    delete pInt;                 //删除单元素
    
    delete[] pDoubleArray;            //删除数组

    还是老话题,一般来说程序是能分配出内存的,但是实在山穷水尽了怎么办?这时候程序就会抛出一个std::bad_alloc异常。注意,这是new 和 malloc 的区别之一。但是难能可贵的是C++提供了一个机制来处理bad_alloc异常,其做法如下:

    void BadAllocateHandler()
    
    {
    
      std::cout << "内存分配失败了" << std::endl;
    
      exit(0);
    
    }
    
    std::set_new_handler(BadAllocateHandler);

    BadAllocateHandler是程序员自己写的当分配失败时的处理函数。而set_new_handler是c++提供的机制。一般来说当山穷水尽的时候你所应该做的事只有两件。要么让程序退出,要么想办法从别的地方挖一些内存来继续分配。

    new是一个关键字。而对于一个程序来说,一切的动作都将回到函数调用。

    所以new的时候到底发生了什么呢?

    当new的时候,首先程序会去调用::operator new()这个函数。然后::operator new()中程序会去调用malloc()。 喔!一切都明了了,原来new的本质也是去调用malloc函数。同理,delete的本质是去调用free()函数。

    虽然new的本质是去调用malloc,但是new 和 malloc还有一点很大的不同。那就是new 出来内存后,new会把对象给构造出来,而malloc只是分配内存。具体例子如下:

    class MyObj {
    
    public:
    
      public MyObj(int value) : val(value) {}
    
      int val;
    
    };
    
    MyObj* obj = new MyObj(4);
    
    MyObj* obj1 = (MyObj*) malloc(sizeof(MyObj));

    new 的做法是在malloc分配出内存后,编译器会直接调用类的构造函数在这片内存中构造出对象。

    注意!只有编译器能直接调用类的构造函数。而使用malloc的话,是无法直接在上面构造出对象的。

    展开全文
  • 在C++中经常遇到内存的开辟和释放问题,最近在做项目的时候遇到了一个关于new和delete内存释放的问题,所以总结下这个问题。在C++ primer中,delete一般用来释放单个对象的内存,delete[]用来释放多个对象的内存。...
  • 关于placement new

    2019-06-29 17:16:06
    昨天去笔了Gameloft,才发现自己还有好多C++的...placement new 是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。...
  • new和malloc

    2020-03-07 10:36:42
    1 new和delete简介   1、“new”,"delete"是C++的一个关键字,同时也是操作符;   2、new创建对象过程:开辟内存,初始化(内置类型,自定义调研构造函数),返回指针;   3、delete释放对象过程:析构;free...
  • 重点:包含动态分配成员的类 ... 以下讨论中将用到的例子: class CExample{public:CExample(){pBuffer=NULL; nSize=0;}~CExample(){delete pBuffer;}void Init(int n){ pBuffer=new char; nSize=n;}private:char *pB...
  • delete this->p; } template T* Append(const ARRAY & other)const { int i; T *p1; p1=new T[this->size+other.size]; for(i=0;i<this->size;i++) p1[i]=this->p[i]; for(int j=0;j...
  •   以下讨论中将用到的例子: class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete pBuffer;} void Init(int n){ pBuffer=new char[n]; nSize=n;} private:
  • 关于智能指针的理解

    2020-06-14 16:13:30
    c++智能指针,即句柄类,用于管理动态内存,自动去回收空间,因为在使用new时,难免会出现以下几种状况: 1.忘记delete内存,这种情况就是我们常说的“内存泄漏”。 2.使用已经释放的对象,这要求我们要清楚变量的...
  • 有两张表,retailcatalogproduct 有一个存储过程 ``` /* *将 RETAILCATALOG 上的 PRICE 数据同步到 PRODUCT 表上的 SALEPRICE */ drop procedure if exists proc_product_saleprice_state_update; create ...
  • 关于vs编译器 /GZ 选项的意思

    千次阅读 2013-01-10 14:45:25
    包括用 0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如 new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如 delete ),0xFD( deFencde Data ) 初始化受保护的...
  • 我在这里只测试了在inverse(true/false),级联cascade(all [save,update,delete,saveorupdate]/ none)的影响下,数据查询方式分别为new方式get两种状况的影响下的删除操作。以下我的代码虽然很啰嗦,但是为了...
  • c# 加密解密相关代码

    热门讨论 2011-09-06 11:04:59
    在第一个GroupBox 中放入3 个TextBox 控件一个Button 按钮,分别用于输入数字、输入加密数字、显示加 密后的数字计算加密信息;在第二个GroupBox 中放入一个TextBox 控件一个Button 按钮,分别用于显示 解密后...

空空如也

空空如也

1 2 3 4
收藏数 71
精华内容 28
关键字:

以下关于new和delete