你们都知道new
了一个变量,须要使用delete
释放内存,而new
出了一个数组,须要使用对应的delete[]
释放内存。但我好像在哪看见过一种说法:针对系统内置类型,使用new分配后的无论是数组仍是非数组形式内存空间用delete
和delete[]
均可以。光说没用,写代码测试一下(测试环境 centos
, g++4.8.5
)。html
内置普通变量:ios
// test.cpp #include <iostream> #include <thread> using namespace std; #define N (1024*1024) // 1M int main() { while(1) { char *a = new char[N]; // 4M //delete[] a; std::this_thread::sleep_for(std::chrono::milliseconds(5)); //5ms延时 printf("running\n"); } } // 编译 g++ test.cpp -o test -std=c++11 // 1. 不delete时,内存一直在涨 // 2. 使用delete 时, 内存不涨 // 3. 使用delete[] 时, 内存不涨
测试发现,说的确实有道理啊,内置类型的数组不必使用delete[]
。c++
因而再测测自定义类型:centos
#include <iostream> #include <thread> using namespace std; #define N (1024*1024) // 1M class A{ public: char a; A() : a('a') { } }; int main() { while(1) { A *a = new A[N]; // 4M //delete[] a; std::this_thread::sleep_for(std::chrono::milliseconds(5)); //5ms延时 printf("running\n"); } } // 1. 不delete时,内存一直在涨 // 2. 使用delete 时, 内存不涨 // 3. 使用delete[] 时, 内存不涨
what?结果和内置类型同样???这是为何,因而赶忙去查一查资料,发现本身对new
和delete
的理解确实错了!赶忙从新总结一波。数组
记住一句话:new
先分配内存,再调用构造函数。delete
先调用析构函数,再释放内存。函数
那么,若是new
了一个数组,调用几回构造函数呢,调用的是那一个构造函数呢;delete
数组和delete[]
数组又分别调用几回析构呢。能够作个实验:测试
#include <iostream> #include <thread> using namespace std; class String { public: // 若是删除无参的构造函数 // new String[]的时候会报错 String() { cout << "String()" << endl; m_data = new char; } String(int n) { cout << "String(int n)" << endl; m_data = new char[n]; } ~String() { cout << "~String()" << endl; delete[] m_data; } private: char* m_data; }; int main() { String* s = new String[3]; // 三次无参构造函数 // delete s; // 一次析构函数 delete[] s; // 三次析构函数 } // 1. new String[3],调用了3次无参的构造函数! // 因此若是没有无参构造函数会报错 // error: no matching function for call to 'String::String()' // 2. 使用delete 时,调用了一次构造函数 // 3. 使用delete[] 时, 调用了三次析构函数
其实看完这个例子,就能明白为何要用delete[]
而不是delete
了,由于只掉用一次析构函数,对于上面的代码是错的,会发生内存泄漏。由于String
类中有指针成员。这些指针成员必须跟随着String
对象的销毁而销毁。this
下面是内存分布图:spa
在使用delete
的时候,其实是会删除三个String
对象占据的内存,可是只有在调用String
类的析构函数的时候,才会销毁对象内部的m_data
变量所指向的字符串。而delete
只会调用第一个对象的析构函数,后面两个String
对象的析构函数不够调用。而delete[]
能够保证这一点。在使用new
的时候,会记录数组的长度,以下图,指针
delete[]
会根据记录的长度决定析构次数。
因此说,其实若是类中没有new
出来的资源,都是栈上的资源,无需调用构造函数来释放资源的话,其实调用delete
和delete[]
没有区别。而若是类中有指针变量,则对于这种对象的数组,必须使用delete[]
。
能够编写代码测试,当一个类中只有栈上的变量的时候,它组成的数组用delete
删除是不会发生内存泄漏的。引言中的测试也证实了这一点。
紧紧记住:new
先分配内存,再调用构造函数。delete
先调用析构函数,再释放内存。delete
只会调用数组第一个对象的析构函数,而delete[]
会调用数组中全部对象的析构函数。虽然有时候没有影响,可是最好仍是遵循规范,防止错误的发生,对于数组都使用delete[]
。
[delete 和 delete []的真正区别](https://www.cnblogs.com/wangj...