本文共 1591 字,大约阅读时间需要 5 分钟。
1、new 是运算符,malloc 时系统函数
2、new 先开辟内存,再调用构造对象的构造函数 malloc 只开辟内存 3、new 可以给开辟的内存进行初始化,malloc 不能初始化 4、new 开辟内存成功返回对象类型的指针,malloc 开辟成功返回void *类型的指针 5、new 开辟失败抛出异常,malloc 返回NULL 6、new 开辟内存给定对象的个数,malloc 需要给定内存块的大小1、delete 是运算符,free是库函数
2、delete 受类型的影响,强制类型转换后的(把一个对象转成int型)后delete 不会调用析构函数,free 不受类型的影响, 3、delete 先析构对象再释放内存,free直接释放内存 4、对数组的释放delete[]ptr free(ptr) 针对delete 与 free第二条的测试class A{ public: A(){ cout << "A()" << endl;} ~A(){ cout << " ~A() " << endl;}};int main(){ A *pa = new A; //delete pa; int *tmp = (int *)pa; //这里delete之后不会调用析构函数 delete tmp; return 0;}
普通new 的大致实现代码,内存申请失败会抛出异常,不能通过返回值是否为nullptr 来判断内存是否申请成功
void *operator new(size_t size){ cout << "new" << endl; void *p = nullptr; p = malloc(size); if(p == nullptr) { throw bad_alloc(); } return p;}
不抛异常的new, 内存申请失败返回nullptr
void *operator new(size_t size){ cout << "new" << endl; void *p = nullptr; p = malloc(size); if(p == nullptr) { throw bad_alloc(); } return p;}
定位new 会在你给定的位置开辟一块内存,这个操作是十分危险的,
int main(){ /* 先申请一块内存,让 pa 指向了它 */ int *pa = new int; /* 在pa释放之前我们有申请了一次,重复申请,这里不会报错 */ int *p = new(pa) int; /* 申请完之后释放了pa */ delete pa; /* 这时候再释放p 程序就会挂掉 */ delete p; return 0;}
有时候我们可能会定位到一正在使用的内存块,不管是修改内存中的内容还是释放了该内存,都是我们不想要看到的。
class A{ private: int mdata;};int main(){ int a = new A; int b = new A[1]; /* 上面的 a 和 b 有什么区别? */}
在这里插入图片描述
可以看出new []在开辟内存的时候会多开辟出4个字节记录对象的个数,在析构的时候可以明确地知道调用多少次析构函数,申请完内存都是返回给用户p处的地址。 如果调用delete 则只析构一次,从p处释放内存。 如果调用delete[] 则析构的次数有p前面的4个字节处,释放的时候p先向前移动4个字节然后再释放。转载地址:http://mtnwi.baihongyu.com/