malloc,calloc,realloc动态开辟空间
malloc()函数开辟空间
在计算机的内存中分为堆区,栈区和静态区
栈区是用来放局部变量和函数形参的,而堆区就是用来存储动态内存开辟的空间的。
malloc具体代码如下
#define MAX 10
#include <stdio.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * MAX);
//此处就通过malloc()函数开辟了10个整形的空间,也就是四十个字节的空间将p指针指向这块开辟的空间。
}
malloc()函数是在堆区进行开辟空间的,而且malloc()开辟的空间不用初始化
if (p == NULL)
{
//由上面的代码可知开辟了一个空间,让p指向这块空间
//此处如果p等于空指针就表示通过malloc()函数开辟的空间没有开辟成功。
printf(“开辟空间失败\n”);
return -1;
}
else
{
//如果开辟成功了
for (int i = 0 ; i < 10 ; i ++)
{
*(p + i) = i;//对该开辟的空间进行赋值
}
calloc()函数开辟空间与free()释放空间
calloc()开辟的空间也是在堆区开辟的
calloc()函数内存在两个参数而malloc()函数内存在一个参数并且calloc()开辟的空间是初始化的
具体代码如下:
int* p = (int*)calloc(10 , sizeof(int));
//该代码也是开辟了十个整形空间第一个参数表示开辟空间的数量,第二个参数表示的是开辟空间的类型的字节数。
if (p == NULL)
{
//此处与上面代码一样此时动态开辟空间失败
printf(“空间开辟失败\n”);
}
else
{
for (int i= 0 ; i < 10 ;i ++)
{
//对calloc()函数开辟的空间内的值进行输出
printf("%d " , *(p + i));
}
free( p );
//当这块开辟的空间用完之后,为了防止内存泄漏要对这些开辟的空间进行释放
p = NULL;
//并将指针p指向空
realloc()函数重新开辟空间并增加空间
由上面的代码可知:
int* p = (int*)calloc(10, sizeof(int));通过calloc开辟了一块空间这时候如果此时想存储的内容这块内存无法进行存储那么这个时候就要用到realloc()函数对开辟的空间进行重新开辟并且增加这块空间
具体代码为:
int* ptr = (int*)realloc(p , 80);
//调整开辟空间的大小
if (ptr != NULL)//此时调整空间成功
{
p = ptr;
//将ptr中的空间和内容赋值给p
}
此时就可以继续用p指向的空间进行存储内容了
最后不要忘记了对开辟的空间进行释放
free( p)//释放空间
p = NULL;
return 0;
动态开辟内存中常出现的错误
- 对NULL指针的解引用操作
//如何避免 对动态开辟函数的返回值进行检测是否是空指针
int main()
{
int* p = (int*)malloc(INT_MAX);
//p是有可能是空指针的,当为空指针的时候,*p就是非法访问内存
*p;
}
2.对动态开辟内存空间的越界访问
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
return -1;
}
else
{
//此处i = 10的时候就越界访问了
for (int i = 0; i <= 10; i++)
{
*(p + i) = 0;
}
}
}
-
对非动态开辟内存使用free()函数
int main()
{
int a = 10;
int* p = &a;free§;//此处对非动态开辟空间进行释放是错误的
return 0;
}
-
对动态开辟的空间的一部分进行释放是错误的
-
对同一块空间进行多种释放
-
忘记释放
以上为动态内存开辟空间的全部内容。