目录
在开始学习之前,我们可以思考,为什么要进行/存在 动态内存分配呢
在学习动态内存分配之前,我们开辟内存的方式主要是在栈区上定义变量等
例如:int val = 20;//在栈空间上开辟四个字节
但是,这种开辟内存空间的方法有两个特点:
一、几个动态内存函数
1.malloc
函数原型:void *malloc( size_t size );
作用:这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
注意:
int *p=(int*)malloc(4*sizeof(int));
开辟4*4个字节的内存,并将地址返回给int*类型的指针变量p;
2.free
函数原型:void free( void *ptr);
作用:用来释放动态开辟的内存。如果不将动态开辟的内存及时free掉,会有内存泄漏的风险。
注意:
int* ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));
free(ptr);//释放ptr所指向的动态内存
ptr = NULL;//及时置空
3.calloc
原型:void* calloc (size_t num, size_t size);
作用:为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
注意:
callloc与 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
举例:
int *p = (int*)calloc(10, sizeof(int));
开辟10*4个字节单位内存,并返回地址至p指针。
4.realloc
原型:void* realloc (void* ptr, size_t size);
作用:
注意:
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。
有两种情况:
a.原有空间之后有足够大的空间
此时,扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
b.原有空间之后没有足够大的空间
二、动态内存分配中的常见错误
1.对null指针解引用
编译器会报错误
2.越界访问动态内存
错误如上 访问到了未开辟的内存时会出现此问题;
3.对非动态内存开辟的函数进行free
例如
void test()
{
int a = 10;
int *p = &a;
free(p);
}
会报出上图错误;
4.多次释放同一片动态内存
和上图报出错误一致
5.忘记free,造成内存泄漏
内存泄漏 关于内存泄漏,可以学习一下这位大佬的博文
加油!