文章目录
- 1.动态分配 new
- 1.引言
- 2.new的实现
- 2.删除 delete
- 3.初始化 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 语法:
- 指针变量名 = n e w new new 类型标识符;
- 指针变量名 = n e w new new 类型标识符 (初始值);
- 指针变量名 = 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 语法:
- d e l e t e delete delete 动态分配内存的指针名
- 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;
使用注意:
- 被释放的指针 a a a 必须是 指向动态分配的内存空间的指针,否则会报错;
- 如果动态分配了一个数组,但是却用
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
0和−1之外的其他值
这是因为 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