C语言:内存的分配与管理

1、内存区域的划分标准:

代码段             存储代码

数据段             静态/全局数据、常量(const)

堆区(heap)      动态内存分配(更灵活的设置容器大小存储数据)

栈区(stack)     局部变量、函数参数

2、内存分配方式的原理:静态分配和动态分配

静态分配:编译器在处理程序源代码时分配(变量)

动态分配:程序执行时按动态要求来分配(由程序员来决定,用完得人为释放)

比较:静态的程序执行前分配,效率高,灵活差,对象是有名字的变量,内存分配和释放由编译器完成;动态对象没有名字的变量,通过指针间接地对它进行操作。

3、理解野指针的概念:

概念:野指针不是空(NULL)指针,二是指向不属于自己的内存指针。

三种形式:

(1)指针变量没有被初始化。

(2)指针p被free或者delete之后,没有将其置NULL,但是p仍然指向这块已经不属于自己的内存。

(3)通过函数返回局部变量的地址。局部变量存放在stack栈中,函数一被执行完,在这个栈中的数据就会被释放,此时返回的指针就没有了指向,也就是函数中的那一块内存已经不属于返回的这个指针了。

4、内存泄露的概念:

内存被分配后被系统记录,但是用完了,最后没有被释放,记录也就没有被删除此时内存一直被占用,即为内存泄露。类似于图书馆,好借好还。

5、理解malloc函数原型的含义:

#include<stdlib.h>

malloc 函数原型:

void * malloc(unsigned int size);

通用类型指针,真正使用时,需要强制转换为要使用的类型

说明:(1)、size这个参数的含义是分配的内存的大小(以字节为单位)

(2)、返回值:失败,则返回值为NULL(空指针)。成功,则返回是一个 指向空类型(void)的指针,即所分配内存块的首地址。

记住:先对返回值做判断?如果为空,分配内存失败。反之,申请成功。

(1) 用malloc申请一块只保存一个整型类型的内存

int *p = (int*)malloc(sizeof(int)

用malloc申请一块能够保存25个整型类型的内存

(2) int *p = (int *)malloc(sizeof(int)*25)

对动态空间的访问方式

对单一内存的访问

*p = 100;

对动态数组的访问

p[1];*(p+1);(p+1)

数组存储数据时:

*(p+i)//循环存储数据过程中,p所指向的一块内存首地址一直没有变过,变化的只是数据在这一块内存中存放的位置。测试过

*p++;//循环存储数据中,p所指向的内存首地址一直在变化,其实,就是一块内存只是存放了一个数据,p就移动指向了另一块空间首地址,接着存下一个数据。测试过

6、释放内存的函数free的含义:

函数原型:free (void *block)//释放的必须是malloc返回的地址

说明:动态内存的申请和释放必须配对

7、注意事项:

(1) 如果函数参数是一个指针,不要指望指针自己去申请动态内存。也就说指针必须指向一个有效的内存区域。

(2)指针消亡了,p=NULL并不代表它所指向的内存会被自动释放;内存被释放了,free(p)并不代表指针会消亡或者成了空指针。必须两者结合。

(3)malloc分配内存后,程序结束前必须使用free()将已分配的内存空间释放。malloc和free必须是一对一的关系,不能一对多即过度释放。

8、知识拓展:

(1)使用calloc函数分配动态内存

函数原型:void *calloc(unsigned n,unsigned size );

作用是:在内存的动态存储区中分配n个长度为size的连续空间,这个空间一般比较大,足以保存一个数组。

意义:用calloc函数可以为一维数组开辟动态的存储空间,n为数组元素个数,每个元素长度为size。这就是动态数组。函数返回指向所分配域的起始位置的指针;如果分配不成功,返回NULL。

例如:

p = calloc(50,4);//开辟50*4个字节的临时分配域,把起始地址赋给指针变量p

(2)使用realloc函数分配动态内存

函数原型:void* realloc(void *p,unsigned int size);

作用:如果已经通过malloc函数或将calloc函数获得了动态空间,想改变其大小,可以用realloc函数重新分配。

意义:用realloc函数将p所指向的动态空间的大小改变为size。p的指向不变,如果分配不成功,返回NULL。

时间: 2024-10-12 20:08:55

C语言:内存的分配与管理的相关文章

深入C语言内存区域分配(进程的各个段)详解(转)

原文地址:http://www.jb51.net/article/39696.htm 一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text).数据段(data)和BSS段.这3个部分一起组成了该可执行程序的文件 (1)代码段(text segment):存放CPU执行的机器指令.通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可.代码段也通常

Java内存管理第二篇 - 内存的分配

Java内存管理无非就是对内存进行分配和释放.对于分配来说,基本类型和对象的引用存储到栈中,常量存储到常量池中,对象存储到堆上,这是一般的分配.而对于回收来说要复杂的多,如果回收不好,还可能造成分配出去的内存得不到回收而造成内存泄漏. 这一篇将简单介绍一下Java内存的分配,下一篇将介绍内存的回收及内存泄漏等知识. 1.JVM内存模型 1.程序计数器(Program Counter Register): 程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,可以理解为是

浅谈C语言内存管理、内存泄露、堆栈

1.内存分配区间: 对于一个C语言程序而言,内存空间主要由五个部分组成:代码段(.text).数据段(.data).静态区(.BSS).堆和栈组成. BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量和静态变量 (这里注意一个问题:一般的书上都会说全局变量和静态变量是会自动初始化的,那么哪来的未初始化的变量呢?变量的初始化可以分为显示初始化和隐式初始化,全局变量和静态变量如果程序员自己不初始化的话的确也会被初始化,那就是不管什么类型都初始化为0,这种没有显示初始

Java内存分配、管理小结

 想写这篇总结酝酿了有个来月了,却始终感觉还差点什么东西,一直未敢动笔. 最近两天连夜奋战,重新整理下前面查阅的资料.笔记,还是决定将它写出来. 现在提出几个问题,如果都能熟练回答的大虾,请您飘过.如以往一样,我是小菜,本文自然也是针对小菜阶层的总结. 首先是概念层面的几个问题: Java中运行时内存结构有哪几种? Java中为什么要设计堆栈分离? Java多线程中是如何实现数据共享的? Java反射的基础是什么? 然后是运用层面: 引用类型变量和对象的区别? 什么情况下用局部变量,什么情况下用

C语言内存分配函数malloc——————【Badboy】

C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文件里,声明例如以下: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(size_t numElements, size_t sizeOfElement); 它们的功能大致类似,

内存连续分配管理方式

内存连续分配方式,是指为一个用户程序分配一个连续的内存空间.它主要包括单一连续分配.固定分区分配和动态分区分配. 单一连续分配 内存在此方式下分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分:用户区是为用户提供的.除系统区之外的内存空间.这种方式无需进行内存保护. 这种方式的优点是简单.无外部碎片,不需要额外的技术支持.缺点是只能用于单用户.单任务的操作系统中,有内部碎片,存储器的利用率极低. 固定分区分配 固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若

c语言内存四区模型

c语言内存四区模型:代码区,全局区(常量区),栈区,堆区 在全局区(常量区),两个字符串完全一样c++编译器只会定义一份 char * getBuf() { char buf[20]; strcpy(buf, "abcde"); return buf; } abcdX?  有乱码! 确实把内存地址返回了,但不能用 被调函数调用完毕,在临时区分配的内存统统消失 char *buf= (char *)malloc(sizeof(char)*20); 手动malloc申请一份内存,由程序员手

C语言内存话题

嵌入式软件工程师学习路线 朱有鹏老师语录:学习如走夜路,人多心里不慌. 1.嵌入式基础预科 2.ARM裸机全集 3.C语言高级专题 4.Uboot和系统移植 5.Linux应用编程和网络编程 6.Linux驱动开发实战 ---------------------------------------------------- 内存这个大话题 C语言:C语言中编译器帮我们管理直接内存地址.通过编译器提供的变量名等来访问内存. 大块内存通过API(malloc free)来申请释放内存. JAVA/C

内存的分配与回收

实验三  内存的分配与回收 物联网工程                      赖燕菲                   201306104147 一.实验目的 为了合理地分配和使用这些存储空间,当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间和使用情况,找出足够的空闲区域给申请者.当作业撤离归还主存资源时,则存储管理要收回占用的主存空间.主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助我们理解在不同的存储管理方式下应怎样实现主存空间的分