13深入理解C指针之---内存管理
该系列文章源于《深入理解C指针》的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教。
内存管理对所有程序都很重要,主要包括显式内存管理和隐式内存管理。其中隐式内存管理主要是自动变量分配内存,变量主要分配在函数的栈帧上。若是静态变量或全局变量,主要分配在程序的数据段,能够被自动分配数值。显式内存分配可以更加灵活高效的管理内存,可以有效避免空间浪费。C语言支持动态内存管理,对象从堆上分配内存,使用内存分配函数和内存释放函数实现内存的动态管理。
一、内存分配流程:缺少任何环节都有可能出现问题
1、使用内存分配函数分配内存主要包括malloc、calloc、realloc、alloca等
2、使用分配的内存支持应用程序
3、使用free函数释放内存,将内存空间返还给系统
隐式内存管理代码如下:
#include <stdio.h> int main(int argc, char **argv)
{
int var1 = ;
int *ptrVar = &var1;
printf("The var1 is %d and address is %p\n", var1, &var1);
printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p\n", *ptrVar, ptrVar, &ptrVar); return ;
}
显式内存管理代码如下:
#include <stdio.h>
#include <stdlib.h> int main(int argc, char **argv)
{
int *var1 = (int *)malloc(sizeof(int));
*var1 = ;
int *ptrVar = var1;
printf("The *var1 is %d and var1 is %p and address is %p\n", *var1, var1, &var1);
printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p\n", *ptrVar, ptrVar, &ptrVar); return ;
}
指针使用完毕,记得释放内存,释放内存,释放内存,重要的事情说三遍,否则容易造成内存泄露。
1)、分配内存时,需要自行把握内存空间的大小,否则可以越界访问数据,代码如下:
#include <stdio.h>
#include <stdlib.h> int main(int argc, char **argv)
{
char *pc = (char*)malloc(sizeof(char) * );
for(int i = ; i < ; i++){
pc[i] = + i;
}
for(int i = ; i < ; i++){
printf("%c", pc[i]);
}
printf("\n");
free(pc); return ;
}
上面代码,申请了6个字节的空间,但是可以使用18个字节的字符。
2)、realloc函数的应用,需要自行把握空间的大小,代码如下:
/* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
2 * 作者代号: *** :guochaoxxl
3 * 版权声明: *** :(魎魍魅魑)GPL3
4 * 联络信箱: *** :guochaoxxl@gmail.com
5 * 文档用途: *** :深入理解C指针
6 * 文档信息: *** :~/WORKM/StudyCode/CodeStudy/cnblogs_understanding_and_using_c_pointers/chapter2/test12.c
7 * 修订时间: *** :2017年第39周 10月01日 星期日 下午01:32 (274天)
8 * 代码说明: *** :演示realloc函数的使用
9 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main(int argc, char **argv)
{
char *arrCh1 = (char *)malloc(sizeof(char) * );
//arrCh1 = "teacherg";
strcpy(arrCh1, "teacherg");
printf("arrCh1: %p and value: %s\n", arrCh1, arrCh1); char *arrCh2 = (char *)realloc(arrCh1, sizeof(char) * );
if(arrCh2) //只要新的内存arrCh2分配成功,函数realloc会自动释放arrCh1
{
printf("Memory Reallocated at: %p\n",arrCh2);
}else{
printf("Not Enough Memory!/n");
free(arrCh1); //若分配内存失败,则需要手动释放内存,否则内存泄露
arrCh1 = NULL; return -;
}
printf("arrCh1: %p and value: %s\n", arrCh1, arrCh1); //只能获取arrCh1的地址,而无法获取内容
strcat(arrCh2, "uo good"); //arrCh2中已包含原来arrCh1中内容,添加新内容
printf("arrCh2: %p and value: %s\n", arrCh2, arrCh2); //获取arrCh2的地址和内容
free(arrCh2); //释放内存 return ;
}
需要注意的是:第17行代码虽然和第18行代码的作用看似是一样的,但是在本例中,只能使用第18行,主要是使用字符串赋值是使用常量池,对后面分配内存的环节有影响,可以自行运行下代码,再思考下就会明白。
至于calloc和alloc函数,比较简单,就不罗嗦了。
13深入理解C指针之---内存管理的更多相关文章
- [翻译]理解Unity的自动内存管理
当创建对象.字符串或数组时,存储它所需的内存将从称为堆的中央池中分配.当项目不再使用时,它曾经占用的内存可以被回收并用于别的东西.在过去,通常由程序员通过适当的函数调用明确地分配和释放这些堆内存块.如 ...
- Unity 全面理解加载和内存管理
最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别.Resources ...
- 深入理解Linux C语言内存管理
问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...
- [深入理解Java虚拟机]<自动内存管理>
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...
- 深入理解java虚拟机,内存管理部分
1,对象回收前会调用finalize()方法,尝试自救,只能调用一次 2,上面横向对比c++的析构函数,但是java有良好的内存管理,而且try/catch做得比较好 3,回收一个常量,1,对象的实例 ...
- 15深入理解C指针之---内存释放
一.手动申请的内存,必须及时进行内存释放,否则容易造成内存泄露.主要代码形式为: #include <stdio.h> #include <stdlib.h> int main ...
- 深入理解JVM(一) -- 自动内存管理机制
Java运行时数据区域分为:程序计数器,虚拟机栈,本地方法栈,Java堆,方法区,运行时常量池,直接内存,结构如下: 1.程序计数器: 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示 ...
- 深入理解JAVA虚拟机 自动内存管理机制
运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Regist ...
- 深入理解Linux内核-内存管理
内核如果给自己分配动态内存 动态内存:RAM的某些部分被永久打分配给内核,用来存放内核代码以及静态内核数据结构:剩余的部分被称为动态内存 连续物理内存区管理: 页框管理:1.页大小的选择,通常情况下主 ...
随机推荐
- cocos2d-x中解决暂停并保存画面和开始的功能
1.调用所有对象的pauseSchedulerAndActions().太麻烦,不太现实,而且有很多对象不易获取. 2.CCDirector::sharedirector()->pause(). ...
- 洛谷 P1593 因子和
https://www.luogu.org/problemnew/show/P1593#sub 利用约数和定理:可以去看一下公式第13条 然后这个题目的话,要求$a^b$,那么我们首先可以先将a分解然 ...
- CF-1114 (2019/02/11)
CF-1114 A. Got Any Grapes? skip B. Yet Another Array Partitioning Task 将n个数分成连续的k组,使得每组的前m大的数字的总和最大. ...
- 20.Yii2.0框架多表关联一对多查询之hasMany
目录 新手模式 hasMany关联模式查询 新建mode层Article.php 新建mode层Category.php 新建控制器HomeController.php 新手模式 用上次的查询结果,作 ...
- logging记录了其他操作的问题
做atm作业的时候,记录转账操作的那个功能的文件里,同时也记录了增加账号和冻结账号的操作 2018-11-28 17:14:51,754 : transfer : INFO : 用户edward向用户 ...
- 光学字符识别OCR-2
灰度聚类 接着我们就对图像的色彩进行聚类.聚类的有两个事实依据: 1.灰度分辨率 肉眼的灰度分辨率大概为40,因此对于像素值254和255,在我们肉眼看来都 只是白色: ...
- luogu2394 yyy loves Chemistry I
练习 #include <iostream> #include <cstdio> using namespace std; long double a; int main(){ ...
- tar.xz结尾的文件的解压缩方法
例如: codeblocks-13.12-1_i386.debian.stable.tar 这个压缩包也是两层压缩,外面是xz压缩方式,里层是tar压缩方式. 解压缩方法: $xz -d ***.ta ...
- day04_07 while循环01
while循环结构: #while 条件: print("any") print("any") 死循环案例 num = 1 while num<=10 : ...
- PHP-7.1 源代码学习:字节码生成 之 "$a = 1"
前言 本文通过分析 "$a=1" 这个 PHP 语句的编译和执行来窥探 php-cli 解释执行逻辑 准备 参考之前的系列文章,在 ubuntu 环境下下载,编译 PHP 源代码 ...