一、malloc

函数原型:

1
void* malloc (size_t size);

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针;

如果开辟成功,返回一个指向开辟的空间的首地址的指针;

如果开辟失败,返回一个NULL指针,因此malloc函数的返回值,一定要做检查;

返回值的类型时void*,所以malloc函数并不知道开辟空间的类型,具体在使用时由使用者自己决定(强制转换);

如果参数size为0,malloc函数的行为是标准未定义的,取决于编译器;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
int main()
{
int arr[10] = { 0 };
int* p = (int*)malloc(sizeof(arr));//动态内存开辟;
if (p == NULL) {
perror("malloc");//是空指针则输出错误代码;
return 1;//终止程序;
}
for (int i = 0; i < 10; i++) {
*(p + i) = i;//赋值;
}
for (int i = 0; i < 10; i++) {
printf("%d ", *(p + i));//输出
}

//没有使用 动态内存释放函数 free ,此时如果程序继续运行,则被malloc函数开辟的空间不会被回收;
//但只要程序退出,系统会自动回收内存空间;
//正常情况下,由动态内存开辟函数所开辟的内存空间,在使用完成后必须被释放并销毁;
free(p);//将p空间中的值销毁;
p = NULL;//p不再指向有效空间;
return 0;
}

二、calloc

函数原型:

1
void* calloc(size_t num,size_t size);

函数的功能是为num个大小为size的元素开辟一块空间,并将空间的每个字节初始化为0;

与函数malloc的区别在于,calloc会在返回地址前把申请的空间的每个字节初始化为全0;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int* p = (int*)calloc(10, sizeof(int));//动态内存开辟;
if (p == NULL) {
perror("calloc");//是空指针则输出错误代码;
return 1;//终止程序;
}
for (int i = 0; i < 10; i++) {
printf("%d ", *(p + i));//输出为:0 0 0 0 0 0 0 0 0 0;
}
free(p);//将p空间中的值销毁;
p = NULL;//p不再指向有效空间;
return 0;
}

三、realloc

函数原型:

1
void* realloc(void* ptr,size_t size);

ptr是需要调整的内存地址,size是调整之后的空间大小;

返回值为调整后的内存的起始地址;

函数在调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间;

//对于内存空间的调整,存在两种情况:

1.原有空间之后的空间足够满足新空间的开辟;

2.原有空间之后没有足够大的空间满足新空间的开辟;

//函数调整失败的情况:

1.realloc失败的时候,返回NULL;

2.realloc失败的时候,原来的内存不改变,不会释放也不会移动;

//注意使用realloc函数改变或开辟空间,最好使用新的变量接收,再将新变量赋值给旧变量;原因是为了避免开辟空间失败返回空指针,导致的旧空间内存泄漏(指针被置空,无法找到旧空间);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int* p = (int*)malloc(40);//开辟40字节空间赋予p;
if (p == NULL) {
perror("malloc");
return 1;
}
for (int i = 0; i < 10; i++) {
*(p + i) = i + 1;
}
int* ptr = realloc(p, 80);//扩容;此时,如果后续内存空间足够,则空间首地址不会改变,但如果后续内存空间不足,则会发现空间首地址改变,即新空间的开辟;
if (ptr != NULL)
{
p = ptr;//扩容成功则将扩容后的空间赋予p;
ptr = NULL;//ptr不再指向有效空间;
}
else
{
perror("realloc");
return 1;
}
for (int i = 10; i < 20; i++)//为扩容后的空间赋值;
{
*(p + i) = i + 1;
}
ptr = realloc(p, 40);//缩容;
if (ptr != NULL)
{
p = ptr;//缩容成功则将扩容后的空间赋予p;
ptr = NULL;//将ptr置空;
}
for (int i = 0; i < 20; i++)//为扩容后的空间赋值;
{
printf("%d ", p[i]);
}
free(p);//将p空间中的值销毁;
p = NULL;//p不再指向有效空间;
return 0;
}

描述文字
© 2024 mengchao666 开心地使用 Stellar 主题,星际地球第
收集了 62 颗星星 ✧ 共 83.3k 粒星尘,好像写完一本 鲁迅 的《呐喊》了啊