C++动态内存分配malloc/new free/delete看这一篇就够了
//动态内存分配问题
//1.栈:一般函数内的局部变量放在这里,由编译器自动分配和释放
//2.堆:程序员使用malloc/new分配,用free/delete释放。程序运行后也会回收,但程序会常年运行
//3.全局/静态存储区:全局变量和静态变量static放这里。程序结束时候系统释放
//4.常量存储区:"I love"
//5.程序代码区:存储程序代码
//堆和栈不同的用途和区别
//1.栈:空间有限。这是系统规定的 int a = 4;分配速度快,程序员无法控制
//2.堆:不超出实际拥有的物理内存,在操作系统允许的分配的最大内存大小,都可以分配。分配速度比栈慢
//可以随时用new/malloc来分配,用free和delete释放掉。非常灵活。
//malloc和free:在c语言中用这对从堆中来分配和释放内存。malloc()和free()是函数。
//malloc(mamory allocation):动态内存分配。
//一般形式:
//void* malloc(int NumByts);NumBytes:要分配的字节数。void *:万能的指针,可以指向任何类型。分配成功,返回执行内存的的指针,失败返回NULL。不使用的时候,用free()函数释放掉,供其他地方使用。
//free:
//void free(void *FirstBytes):将之前用malloc分配的空间还给程序(操作系统),释放了内存。被系统回收,在需要的时候再次分配
int* p = NULL;//等价于数字0
p = (int *)malloc(sizeof(int));//在堆中分配4个字节,存储一个整数。
if (p) {
//分配成功
*p = 5;
cout << *p << endl;
free(p);//释放掉,千万不要忘记。
}
char* point = NULL;
point = (char*)malloc(sizeof(char) * 100);//100个位置
if (point)
{
strcpy(point, "hello world!");
strcpy_s(point, 100,"hello world!");//更安全的字符串拷贝函数,
cout << point << endl;
free(point);
}
int* p = (int*)malloc(sizeof(int) * 100);//分配放下100个整数的内存空间
if (p) {
int* q = p;
*q++ = 1;//==>*(q++)
*q++ = 5;
cout << *p << endl;
cout << *(p + 1) << endl;
free(p);
}
//new和delete:是运算符(表示符),c++中使用,不再使用malloc/free.分配和释放内存
//new的使用格式
//1)指针名 = new 类型表示符;
//2) 指针名 = new 类型符标识符(初始值)//注意圆括号,表示初始值
//3) 指针名 = new 类型表示符[内存单元个数] //注意是[]
int* myint = new int;
if (myint) {
*myint = 8;
cout << *myint << endl;
delete myint;
}
int* myint = new int(18);
if (myint) {
cout << *myint << endl;
delete myint;
}
int* pa = new int[100];
if (pa) {
int* q = pa;
*q++ = 12;
*q++ = 18;
cout << *pa << endl;
cout << *(pa+1) << endl;
//释放内存
delete[] pa;//释放int pa数组内存空间
//new的时候使用[],delete的时候必须有[],[]必写数组大小
}
//额外补充知识
//1).两者都是配对使用,有开辟必有释放
//2).free/delete 不要重复调用
//malloc/free 和 new/delete区别:
//new 多做了初始化工作,调用构造函数,delete不但释放内存,还有额外工作,比如调用析构函数
char* p = NULL;//NULL实际就是0
char* q = nullptr;//避免指针和整数混淆
int* p = nullptr;
int a = nullptr; 不可以
int b = NULL;//可以
//似乎 NULL==nullptr,实际上不等
if (q == NULL) {
cout << "good" << endl;
}
//避免使用nullptr能够避免在整数和指针之间混淆
cout << typeid(NULL).name() << endl;
cout << typeid(nullptr).name() << endl;
//实际上是不同类型。
//对于指针的初始化,能用nullptr全部取代NULL。
int* myint = new int(18);
if (myint != nullptr) {
cout << *myint << endl;
delete myint;
}