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.页大小的选择,通常情况下主 ...
随机推荐
- 沙盒(SandBox)
iOS 应用沙盒机制就是指 iOS 应用程序只能在为该程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本 ...
- 【转】VC自定义消息
MFC一般可利用ClassWizard类向导添加消息和消息处理函数,但用户自定义消息必须手工输入,现将vc自定义消息方法步骤记录如下: (1)定义消息 利用#define语句直接定义用户自己的消息(既 ...
- 51nod——2502最多分成多少块
数据范围好小... 题目中没说要升序降序,不过样例解释里可以看出是要升序. #include <bits/stdc++.h> using namespace std; ],b[],visi ...
- 获得函数返回值类型、参数tuple、成员函数指针中的对象类型
//function_traits.h,获得函数返回值类型.参数tuple.成员函数指针中的对象类型 //参考https://github.com/qicosmos/cosmos/blob/maste ...
- 【TCP/IP】【网络基础】网页访问流程
引用自 <鸟哥的linux私房菜> http://cn.linux.vbird.org/linux_server/0110network_basic_1.php#ps7 那 TCP/IP ...
- phpstudy2016+phpstorm2017-3+xdebug+chrome
1. 勾选Xdebug 后 phpstudy 会自动重启服务 [XDebug] xdebug.profiler_output_dir="D:\phpStudy\tmp\xdebug" ...
- Python: simple drawings
import cv2; # OpenCV Python import numbers; import numpy as np; import math; import matplotlib; impo ...
- python3爬取墨迹天气并发送给微信好友,附源码
需求: 1. 爬取墨迹天气的信息,包括温湿度.风速.紫外线.限号情况,生活tips等信息 2. 输入需要查询的城市,自动爬取相应信息 3. 链接微信,发送给指定好友 思路比较清晰,主要分两块,一是爬虫 ...
- FIFO buffer 和普通buffer区别
1.FIFO可以说一块具体的硬件存储设备,也可以说程序在内存中开辟的一段内存区域.而buffer往往就是一段缓冲的数据区域 2.FIFO的数据是先进先出的,而buffer没有这个限制,可以全局访问 3 ...
- linux+ARM学习路线
学习步骤如下: 1.Linux 基础 安装Linux操作系统 Linux文件系统 Linux常用命令 Linux启动过程详解 熟悉Linux服务能够独立安装Linux操作系统 能够熟练使用Linux系 ...