C语言学习之堆内存

什么是堆内存:

一种由程序员手动管理的内存,它的申请和释放都需要显式的调用函数来实现。

为什么使用堆内存:

1、栈内存的大小有限。
2、栈内存中的数据随时可能被释放。

如何使用堆内存:

C语言对堆内存的管理是以标准库函数形式实现的,头文件stdlib.h

void *malloc(size_t size);

功能:从堆内存申请size个字节内存,如果size值为0,则返回NULL。
返回值:所申请到的内存的首地址,必须与指针配合使用。

注意:所申请到的内存没有初始化过,里面的内存是不确定的,可以使用以下函数对内存进行初始化。

#include <string.h>

void *memset(void *s, int c, size_t n);

功能:把内存的值按字节数设置为c

s:被初始化的内存的首地址
c:内存中要存放的值
n:初始化的字节数

返回值:完成初始化的内存首地址。

#include <string.h>

void bzero(void *s, size_t n);

功能:把内存初始化为零

s:被初始化的内存的首地址
n:初始化的字节数

void free(void *ptr);

功能:从堆中释放一块内存

ptr:被释放内存的首地址,应该是malloc函数的返回值

注意:内存一旦释放后,指向它的指针就无效了(野指针),为了避免发生意外,应立即把指针置为空。

扫描二维码关注公众号,回复: 6110863 查看本文章

void *calloc(size_t nmemb, size_t size);

功能:从堆内存分配nmemb次size个字节的内存。
返回值:申请到内存的首地址,如果nmemb或size为0,则返回NULL。

注意:此函数所申请到的内存会被初始化0,但它的速度没有malloc快。

void *realloc(void *ptr, size_t size);

功能:调整已经分配内存的大小,又可以衍生出分配内存、释放内存的功能。

ptr:被调整的内存首地址,如果ptr为NULL,就相当于在申请内存。
size:希望调整后的大小,如果size为0,就相当于在释放内存。
返回值:调整后的内存首地址,一定要用ptr接收。

注意:当对ptr指向的内存调大时,如果后续内存已经使用无法直接调整,系统会另外再开辟一块符合要求的内存,并把ptr那块内存中的数据拷贝过去,原ptr就会被释放。

使用堆内存要注意的问题:

从堆分配的内存之间有"空隙",4~12字节,这个空隙中存放的数据是有意义的(只需要4个字节,其它的是为了保持对齐,以16字节),猜测里面存储的是接下分配内存所需要使用的信息。

堆内存越界:
堆内存可以越界,在使用时基本不会出错,但是接下对释放、或再分配内存就可能产生错误(越界会破坏堆内存的维护信息导不能继续管理)。

往后越界:会影响后续内存的分配。
往前越界:会影响内存的释放。

malloc和free函数本身不会出错,它们的出错是由于之前的内存越界造成的。

堆内存的释放:
1、不能重复释放,会造成堆崩溃。
2、可以释放空指针

内存泄漏:
我们把由于业务逻辑的错误导致无法释放的内存叫泄漏的内存。
程序结束后属于它的资源会全部释放包括堆内存,这样是不是就不会内存泄漏了。是的,但是有些程序不能随意退出。
遵循"谁申请谁释放"的规则能尽可以的减少内存泄漏的情况,写malloc时就把free一起写了,与malloc成对出现。

内存碎片:
已经释放的内存,但不能被再次使用,这叫内存叫做内存碎片。
内存碎片不是错误,它是由于内存的释放时间和分配时间不协调造成的。
内存碎片无法避免(天然形成的),只能尽量减少:

1、尽量使用栈内存,只有在数据量比较多的时候再使用堆内存。
2、尽量申请大块内存(多分配一些,有备无患)。
3、不要频繁的申请释放内存。

如何调试"内存"错误(Linux系统下):

当一段程序出现内存错误时,操作系统的内核会把当前程序的内存映像存储到core文件中,内核抛出core文件叫吐核。
如果没有产生core文件,执行一下命令:ulimit -c unlimited

什么是core文件:
当程序崩溃时,内核会把内存的使用情况生成一个core文件中,产生在当前目录下,可以在core文件加入调试信息,以此来定位错误的位置。

在程序中加入调试信息:gcc -g test.c -> 生成带调试信息的可执行程序,执行这个程序:./a.out 就可以产生段调试信息的core文件。

通过gdb(GNU公司为了调试内核而开发的一款程序调试工具)定位错误位置:

1、gdb ./a.out core 进入gdb
2、会显示出错误产生的原因
3、where会定位到错误产生的代码
4、q键退出

猜你喜欢

转载自blog.csdn.net/weixin_43504629/article/details/89790518