目录
重点:
(一)为什么动态内存分配
之前我们见过两种变量开辟空间的方式:
int a=10;
char arr[20]="Hello World!";
上述的两种开辟方式有两个特点;
1:空间的大小是固定的
2:数组在定义时必须指定数组的长度
(二)动态内存分配函数介绍
首先我们来看malloc函数,它的函数原型是:
void* malloc (size_t size);
这个函数会向操作系统申请一块连续可用的空间,并返回这块内存的地址
~如果开辟成功,返回这块内存的地址;
~如果开辟失败,返回NULL.
~返回类型是void*,所以malloc函数并不知道你要申请这块空间给什么样的数据类型使用,因此,
在使用mallc函数的时候一定进行强制类型转换。
~函数参数size是你所要申请的空间的大小,以字节为单位。
举例:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p=(int *)malloc(sizeof(int)*10);//p指向了可以存放10个整型数据的空间
return 0;
}
c语言也为我们提供了释放空间的函数fee,函数原型如下:
void free (void* ptr);
free函数是用来释放我们申请的空间的:
~参数ptr是指向申请的空间
~如果参数ptr指向不是动态申请的空间,那么free的行为是未定义的。
~如果参数ptr指向NULL那么free就不产生任何的效果。
举例:
#include <stdio.h>
int main()
{
//代码1
int num = 0;
scanf("%d", &num);
int arr[num] = {0};
//代码2
int* ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));
if(NULL != ptr)//判断ptr指针是否为空
{
int i = 0;
for(i=0; i<num; i++)
{
*(ptr+i) = 0;
}
}
free(ptr);//释放ptr所指向的动态内存
ptr = NULL;//是否有必要?
return 0;
}
v
我们用malloc申请的空间是没有被初始化的,c语言为我们提供了另外一个申请空间的函数calloc函数,函数原型如下:
void* calloc (size_t num, size_t size);
~函数的功能是为num个大小为size的元素开辟空间,并把这块空间初始化为0;
举例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)calloc(10, sizeof(int));
if(NULL != p)
{
//使用空间
}
free(p);
p=NULL;
return 0;
}
所以当我们需要申请一块空间你并且需要对它初始化时,就要使用calloc函数
而在程序运行的过程中需要的空间可能会发生变化,所以c语言为我们提供了重新申请空间的函数
relloc。函数原型如下:
void* realloc (void* ptr, size_t size);
~ptr是需要调整空间的地址。
~size调整后的空间大小,字节为单位。
~返回值是调整后的空间的地址。
relloc在调整空间的时候有两种情况:
1:原来空间的后面有最够的空间进行调整,那么就会在原来的空间后面追加空间
2:原来空间的后面没有足够的空间进行调整,那么就开辟一块新的空间,把原来空间中间中内 容拷贝过来,返回新的空间的地址。
(三)常见动态内存的错误
1:对NULL指针解引用
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
2:对开辟的空间越界访问
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}
3:对非动态开辟的内存free
void test()
{
int a = 10;
int *p = &a;
free(p);//这里就会报错
}
4:使用frees释放申请空间的一部分
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
5:对同一块内存多次释放
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
6:申请内存忘记释放导致内内存泄露
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main
{
test();
while(1);
return 0;
}