1. 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 在哪里? _A___ * char2 在哪里?A ___pChar3 在哪里? __A__ * pChar3 在哪里? _D___ptr1 在哪里? ___B_ * ptr1 在哪里? _B___2. 填空题:sizeof ( num1 ) = __40__ ;sizeof ( char2 ) = _5___ ; strlen ( char2 ) = _4___ ;sizeof ( pChar3 ) = __4/8__ ; strlen ( pChar3 ) = ___4_ ;sizeof ( ptr1 ) = __4/8__ ;3. sizeof 和 strlen 区别?1.sizeof是C语言中的一个单目运算符,用来计算数据类型所占空间的大小,单位为字节;而strlen是一个函数,用来计算字符串长度。#include <stdio.h> int main() { printf("int=%d\n",sizeof(int)); //4 printf("char=%d\n",sizeof(char)); //1 printf("float=%d\n",sizeof(float)); //4 printf("double=%d\n",sizeof(double)); //8 printf("short=%d\n",sizeof(short)); //2 printf("long=%d\n",sizeof(long)); //4 printf("long double=%d\n",sizeof(long double)); //8 return 0; }
#include <stdio.h> #include <string.h> int main() { char arr1[] = "abcd"; char arr2[] = { 'a','b','c','d' }; printf("strlen1=%d\n", strlen(arr1));//4 printf("strlen2=%d\n", strlen(arr2));//随机数 printf("sizeof1=%d\n", sizeof(arr1));//5 printf("sizeof2=%d\n", sizeof(arr2));//4 return 0; }
- 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
- 堆用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段--存储全局数据和静态数据。
- 代码段--可执行的代码/只读常量。
2. C语言中动态内存管理方式:malloc/calloc/realloc/free
这个函数向内存申请一块连续可用的空间,并返回指向这个空间的指针
这个和malloc的区别就是,把每个空间的每个字节初始化为0,malloc不会初始化
int main()
{
int* p1 = (int*)malloc(sizeof(int));
free(p1);
int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, sizeof(int) * 10);
free(p3);
return 0;
}
3. C++内存管理方式
new 和 delete 操作符进行动态内存管理 。
都是在堆上开辟,也没有初始化
new一个int,初始化为10
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。
自定义类型,开空间+构造函数
struct ListNode
{
ListNode* _next;
ListNode* _prev;
int _val;
ListNode(int val)
:_next(nullptr)
,_prev(nullptr)
,_val(val)
{}
};
int main()
{
ListNode* node1 = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);
return 0;
}
总结:
C++的new和delete
1.用法上进行调整,更加简洁
2.自定义类型,new支持开空间+初始化
4. operator new与operator delete函数
4.1 operator new与operator delete函数
new 和 delete 是用户进行 动态内存申请和释放的操作符 , operator new 和operator delete是系统提供的全局函数 , new 在底层调用 operator new 全局函数来申请空间, delete 在底层通过 operator delete 全局函数来释放空间。
operator new是对new的封装->失败抛异常,实现new
operator delete是对delete的封装->
5. new和delete的实现原理
5.1 内置类型
如果申请的是内置类型的空间, new 和 malloc , delete 和 free 基本类似,不同的地方是:new/delete 申请和释放的是单个元素的空间, new[] 和 delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛异常,malloc 会返回 NULL 。
5.2 自定义类型
new 的原理1. 调用 operator new 函数申请空间2. 在申请的空间上执行构造函数,完成对象的构造delete 的原理1. 在空间上执行析构函数,完成对象中资源的清理工作2. 调用 operator delete 函数释放对象的空间new T[N] 的原理1. 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对象空间的申请2. 在申请的空间上执行 N 次构造函数delete[] 的原理1. 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理2. 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间
![](https://img-blog.csdnimg.cn/direct/bc6bb184e43c4ab7a02a9ec39d32828c.png)
6.错误的操作
1.第一个
int* p1 = new int[10];
delete p1;new []的底层是operator new[ ]
这个不存在内存泄漏
2.第二个
class A
{
public:
A(int a=0)
:_a(a)
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
A* p2 = new A[10];
delete p2;
return 0;
}
有析构函数
没有析构函数
总结:
一定要匹配使用!!!