iOS学习08之C语言内存管理
本次主要学习和理解C语言中的内存管理
1、存储区划分
按照地址从高到低的顺序:栈区,堆区,静态区,常量区,代码区
1> 栈区:局部变量的存储区域
局部变量基本都在函数、循环、分支中定义
栈区的内存空间由系统自动分配和回收
栈顶,栈底:先定义的局部变量存储区域从栈底开始分配,后定义的局部变量向栈顶分配
特点:先进后出,后进先出
当函数、循环、分支结束后,局部变量的生命周期结束,不能被使用,由系统自动回收内存空间
 void test1() {
     int a = ;
 }
 void test2() {
     int a;  // 栈区不会将数据清空,故输出为上个变量的值
     printf("a = %d\n", a);
 }
 int main(int argc, const char * argv[]) {
      test1();
      test2();
 }
运行结果

运行的结果a = 100是函数test1()中的值,只是当函数test1()运行结束后,栈区内存被自动回收,但是栈区不会将数据清空,当函数test2()再定义一个变量且不进行初始化时,输出就是上个变量的值。
栈区的内存安全问题:在函数中返回栈区的地址是不安全的!
2> 静态区:静态变量和全局变量的存储区域
静态区的内存空间由系统自动分配和回收
生命周期和整个程序一样长
 int test3(int num) {
     static int s = ;
     s++;
     return num += s;
 }
 int main(int argc, const char * argv[]) {
   printf("%d\n", test3());
   printf("%d\n", test3());
 }
运行结果

为什么第二次的运行结果是12呢?
因为用static修饰的变量称为静态变量,它只能初始化一次,第二次函数调用时,static int s = 5; 并没有执行,故 s 的值为,最后的结果是
3> 常量区:常量的存储区域
常量区的内存空间由系统自动分配和回收
常量区的内容只能读取不能修改
4> 代码区:所有的语句编译成二进制指令存放在代码区
代码区的内存空间由系统自动分配和回收
代码区的内容只能读取不能修改
程序结束后,代码区的内存空间由系统回收
5> 堆区:由编程人员手动管理的区域(手动申请,手动释放)
2、内存分配函数
1> void *malloc(size)
void * 为任意类型的指针
函数的作用:在堆区申请size个字节的存储空间,然后把存储空间的首地址返回
在堆区申请一块内存空间存放字符串
char str[] = "zifuchuan";
char *p = malloc(strlen(str) + ); strcpy(p, str);
printf("%s\n", str);
在堆区申请一块内存空间存放结构体变量
     Student stu = {"xiaoming", , 'm'};
     Student *p = malloc(sizeof(Student));
     *p = stu;
*p是结构体指针,结构体指针访问结构体成员变量的两种方法如下:
第一种:(*p).成员变量名
printf("第一种:(*p).成员变量名:name = %s, age = %d, gender = %c\n", (*p).name, (*p).age, (*p).gender);
第二种:使用指向运算符:-> ,格式:结构体指针变量(p) -> 成员变量
printf("第二种:使用指向运算符:->:name = %s, age = %d, gender = %c\n", p->name, p->age, p->gender);
2> void free(void *)
释放开辟的存储空间
完整的管理堆区内存代码
int *p = malloc(sizeof(int));
*p = ;
printf("%d\n", *p);
free(p);
p = NULL;
在C语言中访问空地址的存储空间会发生崩溃
int *p = malloc(sizeof(int));
2 *p = ;
printf("%d\n", *p);
free(p);
p = NULL; printf("%d\n", *p);//访问空地址
运行结果

野指针异常
野指针:指针指向了不属于自己管理的存储区域
int *p = malloc(sizeof(int));
*p = ;
printf("%d\n", *p);
free(p);
printf("%d\n", *p); // 野指针异常
练习:输入3个单词,动态分配内存保存单词,并在最后输出。
提示:定义一个指针数组 char * words[3] = {0}; 保存堆区空间的地址,堆区空间存储数据。
     char *words[] = {};
     char string[] = {};
     for (int i = ; i < ; i++) {
         printf("请输入一个单词:\n");
         scanf("%s", string);
         getchar();
         // 根据单词的长度,在堆区开辟存储空间
         words[i] = malloc(strlen(string) + );
         // 把输入的字符串拷贝到堆区内存中
         strcpy(words[i], string);
     }
     printf("输出:\n");
     for (int i = ; i < ; i++) {
         printf("%s\n", words[i]);
         free(words[i]);
     }
3、其他的内存操作函数
1> void *calloc(int n, unsigned size)
在堆区申请n * size 个字节的存储空间,并把存储空间的首地址返回
会将存储空间做清0操作,效率比malloc低
int *p = malloc(sizeof(int) * );
printf("%d %d %d %d\n", *p, *(p + ), *(p + ), *(p + ));
int *q = calloc(, sizeof(int));
printf("%d %d %d %d\n", *q, *(q + ), *(q + ), *(q + ));
运行结果

2> void *realloc(void *, size)
在给定的地址空间的基础上,如果当前指针的地址足够大,那么将地址扩大,如果空间不足,那么重新找一块新的存储空间,然后释放原来指针指向的存储空间,把新的地址返回
int *p_old = malloc(sizeof(int));
printf("%p\n", p_old); int *p_new = realloc(p_old, );
printf("%p\n", p_new);
3> void *memset(void *, int, size)
在给定的地址空间开始,将 int 型的数值拷贝 size 次
int *p = malloc(sizeof(int));
memset(p, , ); // 将p指向的存储空间的数据置为0
4> void *memcpy(void *p, const void *q, unsigned long size)
从q指向的存储空间开始拷贝size个字节的数据到p指向的存储空间
char name[] = "hello";
memcpy(name, "hi", );
printf("%s\n", name);
5>int memcmp(const void *p, const void *q, size)
从p,q指向的地址开始比较size个字节的数据,相等为0,不等为-1
     int num1[] = {, , };
     int num2[] = {, , };
     int result = memcmp(num1, num2, sizeof(num1));// 相等为0,不等为-1
     printf("result = %d\n", result);
iOS学习08之C语言内存管理的更多相关文章
- 深入理解Linux  C语言内存管理
		
问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...
 - 【转】iOS夯实:ARC时代的内存管理
		
iOS夯实:ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature that provides autom ...
 - Objective-C 高级编程:iOS与OS X多线程和内存管理
		
<Objective-C 高级编程:iOS与OS X多线程和内存管理> 基本信息 原书名: Pro Multithreading and Memory Management for iOS ...
 - iOS夯实:ARC时代的内存管理
		
iOS夯实:ARC时代的内存管理 文章转自 ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature tha ...
 - Go语言内存管理(一)内存分配
		
Go语言内存管理(一)内存分配 golang作为一种"高级语言",也提供了自己的内存管理机制.这样一方面可以简化编码的流程,降低因内存使用导致出现问题的频率(C语言使用者尤其是初学 ...
 - C语言 内存管理(转)
		
转自 https://blog.csdn.net/u011616739/article/details/61621815 C语言 内存管理 1.内存分区 C源代码进过预处理.编译.汇编和链接4步生成 ...
 - 【Spark-core学习之八】 SparkShuffle & Spark内存管理
		
[Spark-core学习之八] SparkShuffle & Spark内存管理环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 ...
 - iOS学习之Object-C语言内存管理
		
一.内存管理的方式 1.iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2.内存问题: 1)野指针异常:访问没有所有权的内存,如果想要安全的访问,必须 ...
 - iOS学习之Object-C语言内存管理高级
		
一.属性的内存管理
 
随机推荐
- http://poj.org/problem?id=3278(bfs)
			
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 76935 Accepted: 24323 ...
 - android DisplayMetrics 获取屏幕分辨率
			
Android 提供DisplayMetircs 类可以很方便的获取分辨率.下面介绍 DisplayMetics 类: Andorid.util 包下的DisplayMetrics 类提供了一种关于显 ...
 - Xcode开发中的6个小技巧
			
Xcode是iPhone和iPad开发者用来编码或者开发iOS app的IDE.Xcode有很多小巧但很有用的功能,很多时候我们可能没有注意到它们,也或者我们没有在合适的水平使用这些功能简化我们的iO ...
 - myeclipse 8.5       注册码
			
刚才启动突然发现MyEclipse原来是收费的...汗一把,到弹出注册框我才知道.....老天啊我活的该有多窝囊.. 弹框很烦人,我一个穷书生既想继续学习又囊中羞涩无力购买,只好用盗版了(找个理由辩解 ...
 - DBCC常用命令小汇
			
DBCC是SQL Server提供的一组控制台命令,功能很强大,掌握一些必要的语句,对操作数据库有不少帮助,所以决定整理一下,发现已有不少类似的整理,减少了不少工作,归类如下: 一.DBCC 帮助类命 ...
 - Enter password for default keyring to unlock
			
file /home/ok/.gnome2/keyrings/login.keyring /home/ok/.gnome2/keyrings/login.keyring: GNOME keyring, ...
 - 无废话Android之内容观察者ContentObserver、获取和保存系统的联系人信息、网络图片查看器、网络html查看器、使用异步框架Android-Async-Http(4)
			
1.内容观察者ContentObserver 如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调 ...
 - 用with实现python的threading,新鲜啊
			
哈哈,2.5以后可用.自动加锁释放,如同操作文件打开关闭一样. #!/usr/bin/env python # -*- coding: utf-8 -*- import threading impor ...
 - WMSYS.WM_CONCAT 函數的用法
			
select t.rank, t.Name from t_menu_item t; 10 CLARK 10 KING 10 MILLER 20 ADAMS 20 FORD ...
 - android 入门-Service实时向Activity通过BroadcastReceiver传递数据
			
引文: http://www.cnblogs.com/linjiqin/p/3147764.html <RelativeLayout xmlns:android="http://sch ...