动态内存分配函数

简介: 一.静态内存分配和动态内存分配二.动态内存分配函数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


目录
相关文章
|
24天前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
31 3
|
15天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
29天前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
113 1
|
1月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
11天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
13 0
|
5月前
|
C语言
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
62 0
|
24天前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
38 0
|
26天前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
60 0
|
26天前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
57 0