#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
//向内存申请10个整型的空间
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)//判断p是否为空指针//错误信息对应的错误码会存储在errno中printf("%s\n", strerror(errno));
//strerror将错误码对应的错误信息打印出来else//开辟空间成功//正常使用空间
int i = 0;
for (i = 0; i < 10; i++)
*(p + i) = i;
for (i = 0; i < 10; i++)
printf("%d ", *(p + i));
//当动态申请的空间不再使用时,就应该还给操作系统free(p);//释放p所指向的动态内存
p = NULL;//防止p所指向的内容被修改return0;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
int i = 0;
int* p = (int*)malloc(5 * sizeof(int));
//开辟五个整型的空间for (i = 0; i < 5; i++)
*(p + i) = i;
//为这五个整型变量赋值
int* ptr = (int*)realloc(p, 40);
//开辟的空间不够,使用realloc函数重新开辟空间//ptr存放的是开辟的新空间的地址if (ptr != NULL)//判断是否开辟成功
p = ptr;
//为了防止开辟空间失败(将p赋为空指针),//用一个新的指针变量ptr来接受realloc函数的返回值for (i = 5; i < 10; i++)
*(p + i) = i;
for (i = 0; i < 10; i++)
printf("%d ", *(p + i));
printf("%s\n", strerror(errno));
free(p);//释放使用完后的空间
p = NULL;//将使用完后的空间重新赋为空指针return0;
输出结果:
3. 常见的动态内存错误
3.1 对NULL指针的解引用操作
错误例子:
#include<stdlib.h>
int main()
int* p = (int*)malloc(INT_MAX / 4);
*p = 20;//如果p的值是NULL,就会有问题free(p);
return0;
不能对空指针(NULL)进行解引用
3.2 对动态开辟空间的越界访问
错误例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
int i = 0;
int* p = (int*)malloc(10 * sizeof(int));
//开辟10个整型的空间if (NULL == p)
exit(EXIT_FAILURE);
for (i = 0; i <= 10; i++)
*(p + i) = i;//当i是10的时候越界访问free(p);
return0;
开辟空间时要注意空间是否足够,不够的话可以用我们之前讲的realloc函数来解决。
3.3 对非动态开辟内存使用free释放
错误例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
int a = 10;
int* p = &a;
free(p);
//此处的 p 指向的并不是动态开辟的空间的内存地址return0;
依旧报错:
并不是什么情况都要用到free函数
3.4 使用free释放一块动态开辟内存的一部分
错误例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
int* p = (int*)malloc(100);
free(p);
//p不再指向动态内存的起始位置return0;
还是会报错:
在使用free函数时,要注意括号中的内容必须为之前开辟的空间的起始地址
3.5 对同一块动态内存多次释放
错误例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
int* p = (int*)malloc(100);
free(p);
free(p);//重复释放return0;
依旧会报错:
为了避免这个问题,我们每次在使用free函数释放完空间之后,可以将起始地址赋值为空指针(NULL)
3.6 动态开辟内存忘记释放(内存泄漏)
错误例子:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
voidtest()
int* p = (int*)malloc(100);
if (NULL != p)
return;
int main()
test();
return0;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct S
int a;
int b[0];//柔性数组成员
int main()
//sizeof(s)实际上计算的是int的大小,也就是柔性数组前面的成员的大小printf("sizeof(s)= %d\n", sizeof(s));
return0;
输出结果:
6.2 柔性数组的使用
使用柔性数组时要单独为其开辟空间
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
struct S
int a;
int arr[0];//柔性数组成员,大小未知
int main()
//假设我的柔性数组中要放10个整型数据,则应该这样开辟内存
struct S* pc = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(int));
//用自定义类型struct S*指针来接收开辟的空间的地址
pc->a = 10;//给a赋值//接下来给柔性数组arr赋值
int i = 0;
for (i = 0; i < 10; i++)
pc->arr[i] = i;//为arr的每个成员赋值printf("%d\n", pc->a);//输出a的值for (i = 0; i < 10; i++)
printf("%d ", pc->arr[i]);//输出柔性数组arr的值free(pc);//释放开辟的空间
pc = NULL;//防止非法访问return0;
输出结果:
若当空间不够时也可以使用realloc函数来为其开辟更多空间:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
struct S
int a;
int arr[0];//柔性数组成员,大小未知
int main()
//假设我的柔性数组中要放10个整型数据,则应该这样开辟内存
struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(int));
//用自定义类型struct S*指针来接收开辟的空间的地址
ps->a = 10;//给a赋值//接下来给柔性数组arr赋值
int i = 0;
struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 20 * sizeof(int));
//开辟额外需要的空间if (ptr != NULL)
ps = ptr;
//若新开辟的空间的地址不为NULL,则将其地址赋值给ps作为新空间的起始地址for (i = 0; i < 10; i++)
ps->arr[i] = i;
free(ps);//释放开辟的空间
ps = NULL;//防止非法访问return0;
调试结果:
6.3 柔性数组的优势
接下来我们来看下面两种写法:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct st_type
int i;
int a[0];
}type_a;
int main()
//代码1
int i = 0;
type_a* p = (type_a*)malloc(sizeof(type_a) + 100 * sizeof(int));
//业务处理
p->i = 100;
for (i = 0; i < 100; i++)
p->a[i] = i;
free(p);
return0;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct st_type
int i;
int* p_a;
}type_a;
int main()
//代码2
type_a* p = (type_a*)malloc(sizeof(type_a));
p->i = 100;
p->p_a = (int*)malloc(p->i * sizeof(int));
//业务处理
int i = 0;
for (i = 0; i < 100; i++)
p->p_a[i] = i;
//释放空间free(p->p_a);
p->p_a = NULL;
free(p);
p = NULL;
return0;