1.C++中内存分配情况
1.1 c++中,我们把内存分为5个区域:
(1)栈: 用于存放函数的局部变量,由编译器自动分配和释放。
(2)堆: 程序员利用malloc/new分配,用free/delete释放。
(3)全局/静态存储区: 用于存放全局变量和静态变量(static),程序结束时,系统自动释放。
(4)常量存储区: 如"i love China"。
(5)程序代码区。
1.2 堆和栈的区别
(1) 栈:系统自动分配,空间有限,速度快,程序员控制不了。
(2) 堆:只要不超过实际拥有的物理内存都可以分配,速度慢,需要程序员进行分配和释放。
2. C语言中内存的分配和释放
2.1 malloc() 和 free()
malloc为函数, 一般形式为:
void *malloc(int NumBytes);
NumBytes: 要分配的字节数。分配成功则返回指向被分配内存的指针,分配失败则返回NULL。
当分配的内存不使用的时候,需要用free()函数将内存释放,供其他地方使用.
free为函数, 一般形式为:
void free(void *FirstByte);
*FirstByte: 需要释放的内存首地址,将之前用malloc分配的内存空间还给操作系统。
2.2 代码示例:
int main(){
int *p = NULL;
//分配一个int大小的内存,由于malloc的返回值为void*, 故利用int* 进行转换成与p同类型
p = (int*) malloc(sizeof(int));
if (p != NULL)
{
//分配成功
*p = 5;
}
cout << *p << endl; //5
free(p); //释放
}
int main(){
char *p = NULL;
//分配100个char字节大小的内存, 利用char*将malloc的返回值void*转换为与p同类型
p = (char*)malloc(100 * sizeof(char));
if (p != NULL)
{
strcpy(p, "hello world");
cout << p << endl;
free(p);
}
}
3. C++中内存的分配和释放
3.1 new()和delete()
new和delete为标识符, C++中采用new和delete进行内存的分配和释放,不再使用malloc与free。
new 一般使用方式:
(1) 指针变量名 = new 类型标识符
(2)指针变量名 = new 类型标识符(初始值)
(3)指针变量名 = new 类型标识符[内存单元个数]
3.2 代码实例
int main(){
int * p = new int;
if (p != nullptr) //c++中和指针相关的空用nullptr
{
*p = 8;
cout << *p << endl; //8
delete p;
}
}
int main(){
int * p = new int(18); //开辟一个整型变量的空间,且该空间存放的值为18
if (p != nullptr) //c++中和指针相关的空用nullptr
{
cout << *p << endl; //18
delete p;
}
}
int main(){
int * p = new int[100]; //开辟一个大小为100的整型数组空间
if (p != nullptr) //c++中和指针相关的空用nullptr
{
int *q = p; //q指向数组的首地址
*q++ = 4; //数组第一个元素赋值为4, 指针q往下个元素地址移动
*q++ = 18;
cout << *p << endl; //4
cout << *(p + 1) << endl; //18
//释放数组内存,需使用delete[]
delete[] p;
}
}
4.内存分配两种方式的注意事项
- 配对使用,有malloc成功必然有free,有new成功,必然有delete.
- free/delete,不要重复调用(第二次调用时可能释放其他正在使用的内存)
5.NULL与nullptr
- NULL实际为0
- 使用nullptr能够避免整数和指针之间发生混淆
- 两者实际类型不同
- 对于指针的初始化, 利用nullptr取代NULL
int main(){
char* p = NULL; //NULL实际为0
char* q = nullptr;
cout << typeid(NULL).name() << endl; //int
cout << typeid(nullptr).name() << endl; //std::nullptr
}