范围for、new内存动态分配、nullptr
一、范围for语句:用于遍历一个序列
1 int v[]{12,13,14,16,18}; 2 for(auto &x : v) // 省了拷贝的动作,提高了系统效率 3 { 4 cout << x << endl; 5 }
二、动态内存分配问题
c中,供程序使用的存储空间,有程序区,静态存储区,动态存储区。
C++中,我们把内存进一步分为5个区域;
(1)栈:一般函数内的局部变量都会放在这里,由编译器自动分配和释放;
(2)堆:程序员malloc/new分配,用free/delete来释放。未释放会引起内存泄漏。
(3)全局/静态存储区:放全局变量和静态变量static.程序结束时系统释放。
(4)常亮存储区
(5)程序代码区
堆和栈不同的用途和区别:
(1)栈空间是有限的。这是系统规定的。分配速度快,程序员也控制不了;
(2)堆:只要不超出实际拥有的物理内存,在操作系统允许你能够分配的最大内存大小,都可以分配给你,分配速度比栈慢,你随时可以用malloc/new来分配,free/delete释放,非常灵活。
malloc和free:在C语言中,用malloc和free从堆中分配和释放内存。malloc/free()是函数
一般形式:
void *malloc(int NumBytes); // NumBytes:要分配的字节数。分配成功则返回指向被分配内存的指针,分配失败则返回NULL;当这段内存你不使用的时候,你应该用free()函数来将内存释放掉,供其他地方使用。
free:
void free(void *FirstByte);将之前用malloc分配的内存空间还给程序(操作系统),也就是说释放了这块内存,即这块内存被系统回收,并在需要的时候由系统分配给其他地方使用。
1 int *p = nullptr; 2 p = (int *)malloc(sizeof(int));// 在堆中分配四个字节。 3 if(p != nullptr) 4 { 5 // 内存分配成功 6 *p = 5; 7 cout << *p << endl; 8 free(p); // 释放掉内存,千万不要忘记。 9 }
1 char *point = nullptr; 2 point = (char *)malloc(100 * sizeof(char)); 3 if(point != nullptr) 4 { 5 strcpy_s(point , 100 , “hello world!”) 6 cout << point << endl; 7 free(point); 8 }
1 int *p = (int *)malloc(sizeof(int) * 100);// 分配可以容纳一百个整数的空间 2 if( p != nullptr) 3 { 4 int *q = p; 5 *q++ = 1; // ==>*(q++) --> *q = 1; q++ 6 *q++ = 5; 7 cout << *p << endl; 8 cout << *(p + 1) << endl; 9 free(p); 10 }
new和delete
运算符(标识符),C++中用new/delete分配和释放内存,不在使用malloc和free来分配和释放内存。
new/delete也和malloc,free一样,分配和释放内存,同时new/delete还做了更多的事情。
new 一般使用格式
(1)指针变量名 = new 类型标识符;
(2)指针类型名 = new 类型标识符(初始值) // 注意这里是圆括号括起来,表示初始值
(3)指针类型名 = new 类型标识符[内存单元个数]; // 注意这里是[]
1 int *myint = new int; 2 if(myint != nullptr) 3 { 4 *myint = 8; 5 cout << *myint << endl; 6 delete myint; // 释放单个myint的空间 7 }
1 int *myint = new int(18); 2 if(myint != nullptr) 3 { 4 //*myint = 8; 5 cout << *myint << endl; 6 delete myint; // 释放单个myint的空间 7 }
1 int *pa = new int[100]; // 开辟一个大小为100的整型数组 2 if(pa != nullptr) 3 { 4 int *q = pa; 5 *q++ = 12; // [0] = 12 6 *q++ = 18; // [1] = 18,执行完,这个q已经指向[2] 7 cout << *pa << endl; 8 cout << *(pa + 1) << endl; 9 delete[] pa; // 释放int pa数组空间 10 } // new时我们用[],那么delete就必须[],[]不写数组大小
额外补充:
(1)配对使用,有malloc 成功必然有free,有new成功必然有delete;
(2)free/delete,不要重复调用。
malloc/free/new/delete区别;
new创建类对象的时候会自动调用类的构造函数,delete删除类对象的时候会自动调用了类的析构函数。
三、nullptr
C++11中引入的新关键字,nullptr代表的也是空指针。
1 //int a = nullptr; // 出错 2 int b = NULL; // OK 3 char *p = NULL; 4 char *a = nullptr; 5 if(p == nullptr) 6 { 7 cout << “NULL == nullptr” << endl; 8 } 9 10 if(a == NULL) 11 { 12 cout << “a == NULL” << endl; 13 }
使用nullptr能够避免在整数和指针之间发生混淆。
1 cout << typeid(NULL).name() << endl; 2 cout << typeid(nullptr).name() << endl;