提示:以下是本篇文章正文内容,下面案例可供参考
动态内存是相对静态内存而言的。所谓动态和静态就是指内存的分配方式。动态内存是指在堆上分配的内存,
而静态内存是指在栈上分配的内存。
我们已经掌握的内存开辟方式有:
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
上面第一行代码是在栈空间上开辟四个字节,第二行代码是在栈空间上开辟10个字节的连续空间
但是上述的开辟空间的方式有两个特点:
1. 空间开辟大小是固定的。
2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。也就是说当我们指定了数组的空间大小,在以后使用中如果需要进行扩容或者缩小是不能进行操作的,这时我们就需要动态存开辟.
我们先来看一下malloc函数:
这里要注意如果参数size为0,则malloc的行为是标准未定义的,取决于编译器
下面的例子来具体看一下malloc函数:
#include
#include
int main()
{
//int arr1[10];//40个字节
//char arr2[40];//40个字节
//申请空间
int* p = (int*)malloc(40);//向内存申请10个整型的大小
if (p == NULL)
{
perror("malloc");//如果错误,打印错误内容
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*p = i;
p++;
}
return 0;
}
经过调试,我们确实发现malloc向内存申请了空间,并进行了初始化
其实当我们在向内存申请了空间并使用后,我们需要释放空间,接下来我们就介绍一下free这个函数
free 函数无返回值,它的功能是释放指针变量 p 所指向的内存单元。此时 p 所指向的那块内存单元将会被释放并还给操作系统,不再归它使用。操作系统可以重新将它分配给其他变量使用。
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
其实当我们在使用malloc动态内存开辟,使用完成后我们需要对其进行内存释放。如果不释放动态申请的内存时,如果程序结束,动态申请的内存由操作系统自动回收,如果不结束,就会形成内存泄漏
,指针变量 p 被释放之后,它仍然是指向那块内存空间的,只是那块内存空间已经不再属于它了而已,并且应该把指针置成空指针,防止后面程序使用这个指针,形成空指针,造成非法访问。
注意:一个动态内存只能释放一次。如果释放多次程序就会崩溃,因为已经释放了,不能再释放第二次。
代码如下(示例):
#include
#include
//
int main()
{
//int arr1[10];//40个字节
//char arr2[40];//40个字节
//申请空间
int* ptr = (int*)malloc(INT_MAX);
int* p = ptr;
if (p == NULL)
{
perror("malloc");
return 1;
}
//
int i = 0;
for (i = 0; i < 10; i++)
{
*p = i;
p++;
}
//释放空间
free(ptr);
ptr = NULL;
我们先来看一下calloc函数:
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
下面的例子来具体看一下calloc函数:
#include
#include
int main()
{
int* p = (int*)calloc(10, sizeof(int));//calloc申请的空间会被初始化为0
return 0;
}
经过调试,我们确实发现malloc向内存申请了空间,并初始化为0
1.memblock 是要调整的内存地址
2.size 调整之后新大小
3.返回值为调整之后的内存起始位置。
4.这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
注意:realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间
补充一点:并且会把旧的空间free释放掉
提示:上面就是一些关于动态内存分配的内容:
Hello world 我们下期见!