下面这道例题用于检测c的内存管理的学习程度,又或者说是学到这里c究竟忘了多少....
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);
}
/*1. 选择题:
选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
globalVar在哪里?__C__ staticGlobalVar在哪里?__C__
staticVar在哪里?_C___ localVar在哪里?___A_
num1 在哪里?__A__
char2在哪里?____ *char2在哪里?___
pChar3在哪里?____ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____
- 填空题:
sizeof(num1) = ____;
sizeof(char2) = ____; strlen(char2) = ____;
sizeof(pChar3) = ____; strlen(pChar3) = ____;
sizeof(ptr1) = ____;
*/
#include<iostream>
using namespace std;
int main()
{
//int*ptr1=new int;//申请1个int的空间
int* ptr = new int(10);//申请10个int的空间并初始化为10
delete ptr;//释放单个空间
return 0;
}
#include<iostream>
using namespace std;
int main()
{
//int* ptr = new int(10);
//int* ptr1 = new int[10];//申请10个int的空间
int* ptr = new int[10] {1, 2, 3, 4};//申请10个int的空间并初始化
delete []ptr;//释放连续空间
return 0;
}
这里相当于部分初始化,只初始化了前4个空间,其他空间默认为0
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p = (A*)malloc(sizeof(A) * 10);
free(p);
A* p1 = new A[2];
delete[]p1;
return 0;
}
在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。
new和delete是用户进行动态内存申请和释放的操作符,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
#include <iostream>
using namespace std;
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
//申请空间 operator new 封装 malloc
//在用operator delete p1指向空间
A* p1 = new A;
delete p1;
//申请空间 operator new 封装 malloc
//在用operator delete []p2指向空间
A* p2 = new A[10];
delete []p2;
return 0;
}
\
#include<iostream>
using namespace std;
int main()
{
int* p1 = (int*)operator new(sizeof(int));//new失败抛异常
int* p2 = (int*)malloc(sizeof(int));
if (p2 == nullptr)//malloc失败返回空
{
perror("malloc fail");
}
return 0;
}
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p1 = new A;//先创建空间,在调用构造函数,
delete p1;//delete先调用析构函数,在释放空间
//-----------------------------------
A* p2 = new A[10];//先创建空间,在调用构造函数10次
delete[]p2;//delete先调用析构函数10次,在释放空间
return 0;
}
class stack
{
public:
stack()//构造
{
cout << "stack()" << endl;
_a = new int[4];
_top = 0;
_capacity = 4;
}
~stack()//析构
{
cout << "~stack()" << endl;
delete[] _a;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
stack p;
stack*p1 = new stack;
delete p1;
return 0;
}
若将delete p1改为 free(p1),会少调用析构函数,直接释放stack空间 导致无法释放堆上申请的4个stack类型的数组,从而导致内存泄露
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p = new A[10];
//delete p;//错误
//free(p);//错误
delete []p;//正确
return 0;
}
正常来说,A*p=new A[10],我们知道会调用10次构造函数,但是delete [] p是怎么知道要调用10次析构函数的呢?
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p = (A*)malloc(sizeof(A));//开好一块空间
if (p == nullptr)
{
perror("malloc fail");
}
//定位new
new(p)A(1);//将p对象中的_a初始化为1
p->~A();
free(p);
return 0;
}
都是从堆上申请空间,并且需要用户手动释放