C++之动态分配new & 删除delete & 初始化memset

1.动态分配 new

1.引言

用new创建数组的优势:由于new创建的对象是在运行时确立的,所以有着具体情况具体分析的优点,那么什么叫做具体情况具体分析呢?

举一个十分贴切的例子:

比如你在度假,已经做好每天的参观计划,可突然有一天天气不好或是你的心情不好,此时你就不想参观了,如果此时是在编译状态,系统是不允许的,你必须按照计划去参观,但运行时状态,系统是允许的,此时你就可以呆在酒店尽情的玩耍了,用new创建数组也有此优点,即数组长度可以根据情况而定


2.new的实现

使用 n e w new new 运算符必须已知数据类型,它会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址;如果申请不成功,则返回空指针 N U L L NULL NULL

n e w new new 运算符返回的是一个指向所分配对象的 指针,对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本身没有标识符名


n e w new new 语法:

  1. 指针变量名 = n e w new new 类型标识符;
  2. 指针变量名 = n e w new new 类型标识符 (初始值);
  3. 指针变量名 = n e w new new 类型标识符 [内存单元个数];

①对于单个变量:

第一种定义方式:

int *a=new int;

表示开辟一个存放整数的存储空间,返回一个指向该存储空间的地址,int *a = new int 即为将一个 i n t int int 类型的地址赋值给整型指针 a a a


对于第二种定义方式:

int *a=new int(6)
cout<< *a <<endl; // 6

也是开辟了一个整型空间,并定义了一个指向该空间的指针 a a a,只是此时同时将指向的整数空间 ∗ a *a a 的值赋值为 6 6 6


②对于数组空间:

第三种定义方式:

int n;
cin>>n;
int* a=new int[n];

对于数组的开辟,要使用方括号 [   ] [\ ] [ ],表示开辟一段连续的含有 n n n 个类型的内存空间


2.删除 delete

对于已经开辟的内存空间,我们还需要手动进行释放

d e l e t e delete delete 语法:

  1. d e l e t e delete delete 动态分配内存的指针名
  2. d e l e t e [   ] delete[\ ] delete[ ] 动态分配的内存的指针名

①对于单个变量:

int* a=new int;
delete a;

int* b=new int(6);
delete a;

②对于数组空间:

int* a=new int[n];
delete[] a;

使用注意:

  1. 被释放的指针 a a a 必须是 指向动态分配的内存空间的指针,否则会报错;
  2. 如果动态分配了一个数组,但是却用 delete p 的方式释放,没有用 [   ] [\ ] [ ],则编译时没有问题,运行时也一般不会发生错误,但实际上会导致动态分配的数组没有被完全释放

3.初始化 memset

m e m s e t memset memset:为大空间结构体或大数组空间初始化或清零

①作用
作用是将某一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作,是对较大的结构体或数组进行清零操作的一种最快方法


②语法
m e m s e t memset memset 语法void* memset(void *s,int val,int len)

表示将 s s s中当前位置及后面的 len个字节用 val 替换并返回 s s s


③使用注意
m e m s e t memset memset 函数按字节对内存块进行初始化,所以不能用它将 i n t int int 数组初始化为 0 和 − 1 0 和 -1 01之外的其他值

这是因为 m e m s e t memset memset 使用的是按字节赋值,即对每个字节赋同样的值,这样组成int型的4个字节就会被赋成相同的值,而由于 0 0 0 的二进制补码全为 0 0 0 − 1 -1 1 的二进制补码全为 1 1 1,不容易弄错


对于 − 1 -1 1 来说,它的二进制为 1 1 1 的反码 + 1 +1 +1,即为 1 1 1 的补码

图解:

在这里插入图片描述


第一种情况:

针对字符串数组

char s[4];
memset(s,'1',4);

结果为:由上述可知,因为是对字节进行修改, c h a r char char 数组 s s s,一共有 4 4 4 字节空间,因此我们将全部的字符数组成员,都改为 ′ 1 ′ '1' 1

s [ 0 ] = s [ 1 ] = s [ 2 ] = s [ 3 ] = ′ 1 ′ s[0]=s[1]=s[2]=s[3]='1' s[0]=s[1]=s[2]=s[3]=1


第二种情况:

针对整型数组

char a[4];
memset(a,1,4);

结果为:仅仅将数组 a a a 的前四个字节,也就是第一个元素 a [ 0 ] a[0] a[0] 4 4 4 个字节中的每一个字节都变成了1,而后三个元素还是未分配内容的状态

即将这个 i n t int int元素的每个字节都变成了0000 0001,再合起来数组得到数组 a 的第一个元素也就是:
a [ 0 ] = 00000001   00000001   00000001   00000001 ( 2 ) = 16843009 a[0]=00000001\ 00000001\ 00000001\ 00000001(2)=16843009 a[0]=00000001 00000001 00000001 00000001(2)=16843009

猜你喜欢

转载自blog.csdn.net/qq_73450915/article/details/130970827