动态内存分配函数

简介: 一.静态内存分配和动态内存分配二.动态内存分配函数1.malloc2.free3.calloc4.realloc

一.静态内存分配和动态内存分配

静态内存分配:静态内存分配的空间都是固定的大小,且分配的是栈区的空间,函数执行结束时这些存储单元自动被释放。


动态内存分配:在程序执行的过程中动态地分配或回收存储空间。动态内存分配的是堆上的内存,堆上分配的内存不会主动释放,需由程序员自己释放或是在程序结束时还给操作系统


内存区域分区


16.png


栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。


堆区(heap):一般由程序员自己分配释放,若程序员不释放,程序结束时可能由OS回收。


静态段(静态区)(static):存放全局变量、静态数据/程序结束后由系统释放。


代码段:存放函数体(类成员函数和全局函数)的二进制代码。


二.动态内存分配函数

在使用动态内存分配函数时,需引用对应头文件(#include


1.malloc


void* malloc(size_t size);


函数的功能:向内存申请一块连续可用的空间,并返回指向这块空间的指针。


若开辟成功,则返回一个指向开辟好空间的指针;若开辟失败,则返回一个NULL指针(因此一定要对malloc函数的返回值进行检查


函数的返回值类型为void*,所以malloc函数并不知道开辟空间的类型,由使用者在使用的时候决定


若参数size为0,此时malloc的行为是标准未定义的,取决于编译器。

#include<stdlib.h>#include<stdio.h>intmain()
{
int*p= (int*)malloc(40);
//对返回值进行检查if (p==NULL)
    {
perror("malloc");
return1;
    }
for (inti=0; i<10; i++)
    {
printf("%d\n", *(p+i));
    }
//释放动态开辟的内存free(p);
p=NULL;
return0;
}


malloc函数不会对空间进行初始化,因此存放内容为随机值

17.png


2.free

void free(void* ptr)


free函数是用来释放动态开辟的内存的。


若参数ptr指向的空间不是动态开辟的,那么free函数的行为是未定义的


若ptr是NULL指针,那么函数什么事都不做


注:在释放动态开辟的内存后,应将ptr置为NULL,因为ptr指针指向的动态开辟的空间已经被释放了后,若ptr仍指向那块空间,后面若使用了ptr访问指向的空间,则非法访问该内存。




3.calloc

void* calloc(size_t num, size_t size)


函数的功能:为num个大小为size的元素开辟一块内存空间,并且把空间的每个字节初始化为0.


calloc函数与malloc函数的区别只在于calloc函数会在返回地址之前将申请的空间的每个字节全部初始化为0

#include<stdlib.h>#include<stdio.h>intmain()
{
int*p= (int*)calloc(10, 4);
//对返回值进行检查if (p==NULL)
    {
perror("calloc");
return1;
    }
for (inti=0; i<10; i++)
    {
printf("%d\n", *(p+i));
    }
//释放动态开辟的内存free(p);
p=NULL;
return0;
}


calloc函数会将空间的每个字节初始化为0

18.png


4.realloc

void* realloc(void* ptr ,size_t size)


realloc函数的功能:


若申请的空间过小或是过大,则可用realloc函数对内存大小进行调整。


ptr:要调整的内存地址


size:要调整之后的大小


在增加空间时,若原本开辟的内存后面有足够的空间,则直接在后面开辟新的空间;


19.png


若后面的空间不够,则realloc会先开辟新的空间,并将旧空间中的数据拷贝到新的空间中,拷贝后则释放旧的空间,最后返回新空间的起始地址


20.png


若开辟失败,则返回NULL,因此应先对返回值进行判断,防止原始数据丢失

#include<stdlib.h>#include<stdio.h>intmain()
{
int*p= (int*)calloc(10, 4);
//对返回值进行检查if (p==NULL)
    {
perror("calloc");
return1;
    }
int*ptr= (int*)realloc(p, 20*sizeof(int));
//判断ptr是否为NULLif (ptr!=NULL)
    {
p=ptr;
ptr=NULL;
    }
else    {
perror("realloc");
return1;
    }
for (inti=0; i<20; i++)
    {
printf("%d\n", *(p+i));
    }
//释放动态开辟的内存free(p);
p=NULL;
return0;
}


realloc函数也不会对新开辟的空间进行初始化

21.png


目录
相关文章
|
3月前
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
54 2
|
3月前
|
存储 C语言
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
87 1
|
3月前
|
C语言
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
49 0
|
1月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
1月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
1月前
【C初阶】内存函数:memcpy+memmove+memset+memcmp
【C初阶】内存函数:memcpy+memmove+memset+memcmp
|
2月前
|
存储 缓存 C语言
【C语言】字符函数,字符串函数,内存函数
C语言中的字符串函数和内存函数
34 0
【C语言】字符函数,字符串函数,内存函数
|
3月前
|
C语言
字符串和内存函数(1)
字符串和内存函数(1)
36 7
|
3月前
|
C语言
【C语言】:4大内存函数
【C语言】:4大内存函数
24 2
|
3月前
字符串和内存函数(2)
字符串和内存函数(2)
34 5

热门文章

最新文章