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(). ...
- Re:从零开始的Linux之路(目录配置)
基于 Red Hat Enterprise Linux 7.5 或者 CentOS 7.4 FHS协议(Filesystem Hierarchy Standard)——文件系统层次化标准 该标准定义了 ...
- apply 与 lambda
Python中的lambda和apply用法 https://blog.csdn.net/anshuai_aw1/article/details/82347016
- python中文件操作的其他方法
前面介绍过Python中文件操作的一般方法,包括打开,写入,关闭.本文中介绍下python中关于文件操作的其他比较常用的一些方法. 首先创建一个文件poems: p=open('poems','r', ...
- Python使用ORM控制MongoDB(MongoEngine)
简介: MongoEngine是一个对象文档映射器(ODM),相当于一个基于SQL的对象关系映射器(ORM) pymongo来操作MongoDB数据库,但是直接把对于数据库的操作代码都写在脚本中,这会 ...
- leetcode-22-string
521. Longest Uncommon Subsequence I find the longest uncommon subsequence of this group of two strin ...
- jenkins匿名用户登录 - 安全设置
最近自己安装配置jenkins,但是跑任务时,发现是匿名账户登录,且提示: 后来发现搭建好jenkins之后,默认就是匿名用户登录的,可以在安装设置菜单里进行账户管理. 1.登录Jenkins服务器, ...
- CodeForces 500E New Year Domino
题意: 从左到右排列着\(n\)个多米诺骨牌,它们分别站在\(x\)轴上的位置\(p_i\)上且高度为\(l_i\). 当第\(i\)个多米诺骨牌向右倒下时,如果\(p_i < p_j \leq ...
- 学习正则有感by魔芋(命名问题)
魔芋: 事实上,我是反感一些特殊的名词.一些名词看上去就让人感觉到抗拒. 关于一个概念用不同的名词来定义,简直是太糟糕了. 举个例子: 匹配一个后面带有exp2的exp1的正则. 写法: exp1(? ...
- Selenium WebDriver- 使用Frame中的HTML源码内容操作Frame
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...