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.页大小的选择,通常情况下主 ...
随机推荐
- cocos2dx 3.x c++代码打包给lua调用过程(mac)
下载cocos2dx 框架,在应用程序->cocos->framework->cocos2d-x-3.x->tools->tolua目录下,一个ini文件对应一个py文件 ...
- 【转】PCA for opencv
对于PCA,一直都是有个概念,没有实际使用过,今天终于实际使用了一把,发现PCA还是挺神奇的. 在OPENCV中使用PCA非常简单,只要几条语句就可以了. 1.初始化数据 //每一行表示一个样本 Cv ...
- 在VMware上安装centos7
1. 下载centos7 64位镜像 linux官网下载:https://www.centos.org/download/ 2. 在VMware上安装centos7 2.1 新建虚拟机 打开虚拟机主页 ...
- NodeJS基础入门-fs文件系统
文件I/O是由简单封装的标准POSIX函数提供.通过require('fs') 使用该模块.所有的方法都有异步和同步的形式. 异步方法的最后一个参数都是一个回调函数.传给回调函数的参数取决于具体方法, ...
- day3-python 登录
import datetime # 1. f = open('users') result = f.read() f.close() user_list = result.split() # user ...
- python hashlib模块学习
目录 hashlib 模块 破解密码 hmac 模块 hashlib 模块 1.干嘛用的: 对字符进行加密,其实就是一个自定义的字符编码表,我们原来接触的是计算机语言0和1然后转化成字符,而hashl ...
- python计算机基础(三)
简述Python垃圾回收机制: 当x=10,赋值x=11,的代码,也就是10没有对应的变量名, 10在python眼中相当于垃圾,就会被清理掉,释放内存. 对于下述代码: x = 10 y = 10 ...
- 【Arduino开发板刷Bootloader01】
其接线方式就是: Programmer(工具开发板) Being programmed(目标开发板) Vcc ...
- BZOJ 3326: [Scoi2013]数数
数位DP,然而式子真的复杂 #include<cstdio> #include<algorithm> #include<cstring> using namespa ...
- Python中的魔术方法详解(双下方法)
介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...