内存分布
例题
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";
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在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____
char2在哪里?____ *char2在哪里?___
pChar3在哪里?____ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____
🌸globalVar:全局变量,在静态区 🌸staticGlobalVar:静态全局变量,也在静态区 🌸staticVar:静态局部变量,在静态区
💥localVar:局部变量,在栈 💥num1:数组,在栈
💥char2是一个数组,在栈上开5字节空间(包括\0了),把数据拷贝过去 💥char2,解引用的时候char2是首元素地址,char2解引用就是首元素,首元素是栈上开的空间,所以char2在栈上
💥pchar3是定义在栈上的局部变量,所以在栈上 🐶pchar3在栈上,但是它指向的空间在常量区,所以*pchar3在常量区
💥ptr1是局部变量,在栈上 🐹 *ptr1在堆
填空: sizeof(num1)=40;因为初始化的时候指定了大小 sizeof(char2) = 5 因为包含了’\0’; strlen(char2) = 4计算长度时遇到’\0’停止; sizeof(pChar3) = 4,pchar3是指针,在32位平台占4个字节_; strlen(pChar3) = 4;“abcd”在常量区,长度还是4 sizeof(ptr1) = 4因为是指针;
sizeof计算的是在空间上占多少字节,字符串包含’\0’ strlen计算字符串长度,遇到’\0’就停止
new操作符
malloc/ calloc /realloc 的区别 |
calloc he malloc 区别 calloc会初始化,相当于malloc+memset,按字节初始化,空间每个字节都初始化为0 realloc扩容,分为原地扩容和异地扩容
int main()
{
int* p1 = (int*)malloc(sizeof(int));
int* p2 = (int*)malloc(sizeof(int) * 5);
int* p3 = new int;
int* p4 = new int[5];
free(p1);
free(p2);
delete p3;
delete[] p4;
p1 = nullptr;
p2 = nullptr;
p3 = nullptr;
p4 = nullptr;
}
总结: malloc/free 和 new/delete 对于内置类型没有本质区别,只有用法的区别 对于自定义类型,new不仅会申请空间,还会调用默认构造函数,让对象初始化; delete会先调用指针类型析构函数,再释放空间给堆
一定要malloc free 和 new / delete ,new[] / delete[] 匹配使用 new失败了以后会要求抛异常,这样才符合面向对象语言的出错处理机制
简单拿个栈举例
class Stack
{
public:
Stack(int capacity=4)
:_top(0)
, _capacity(capacity)
{
_a = new int[capacity];
}
~Stack()
{
delete[] _a;
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
Stack s1;
Stack* ps2 = new Stack;
delete ps2;
return 0;
}
operator new与operator delete函数
operator new 和operator delete是系统提供的 全局函数
Stack* pst1 =(Stack*) operator new(sizeof(Stack));
Stack* p1 = new Stack[10];
Stack* p1 = (Stack*)operator new[](sizeof(Stack) * 10);
operator new 和operator delete 就是对malloc 和free 的封装 operator new中调用malloc申请内存,失败以后,改为抛异常处理错误,这样符合c++面向对象语言处理错误的方式
new和delete原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数释放对象的空间
定位new表达式
Stack* sp1 = (Stack*)malloc(sizeof(Stack));
new(sp1)Stack;
free(sp1)
Stack* sp2 = new Stack();
delete sp2;
Stack* sp3 = (Stack*) operator new(sizeof(Stack));
new(sp3)Stack();
sp3->~Stack();
operator delete(sp3);
内存泄露危害
1.内存泄露 – 动态申请的内存,不使用了又没有主动释放,就存在内存泄露 2.内存泄漏的危害 ? a.出现内存泄露的进程正常结束,进程结束时这些内存会还给系统,不会有什么伤害 b.出现内存泄露的进程非正常结束,如僵尸进程 c.需要长期运行的程序出现内存泄露,危害很大,系统会越来越慢,甚至宕机 --服务器程序
|