C/C++ Learning
目录
1. C/C++中的关键字
2. C/C++中的标识符
3. 编译选项MD(d)、MT(d)编译选项的区别
4. C++类模板、函数模板
5. C++修饰符
6. 调用约定
7. 错误处理
8. 环境表
9. 内存管理与进程映射
10. 系统调用
11. 文件管理(Unix C)
12. 进程管理
1. C/C++中的关键字
0x1: extern关键字
在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,这是什么原理呢?
. C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称
. 而C语言则不会,C语言没有重载这个概念
. 如果在C++程序中直接使用extern进行函数引入,则可能会因为重载的关系导致函数名被"重定义"
. 因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern "C"进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名
下面是一个标准的写法:
//在xx.h文件的头上
#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif
#endif /* __cplusplus */
…
…
//.h文件结束的地方
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
extern关键字有两个作用
. 引入别的模块的"extern变量/函数"
置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义(逐个obj搜索)
例如: extern int iRI;
//就是告诉编译器:你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量
当它与"C"一起连用时,如: extern "C" void fun(int a, int b);
则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时,因为要支持函数重载的原因,会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样)
/*
现代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部
例如在头文件中: extern int g_Int;
要注意的是,它是一个声明不是定义,在其他文件的某个地方需要真正定义并声明这个变量
全局变量使得真正意义上的超全局变量得以实现,因为C/C++编译器的单文件编译的限制,传统的全局变量只能在本文件域内生效,而extern能够把作用域扩展到整个obj链接过程中
*/ . 在C++文件中调用C方式编译的函数
C方式编译和C++方式编译
相对于C,C++中新增了诸如重载等新特性。所以全局变量和函数名编译后的命名方式有很大区别。
int a;
int functionA();
对于C方式编译:
int a;=> _a
int functionA(); => _functionA
对于C++方式编译:
int a; =>xx@xxx@a
int functionA(); => xx@xx@functionA
可以看出,因为要支持重载,所以C++方式编译下,生成的全局变量名和函数名复杂很多。与C方式编译的加一个下划线不同,如果C++文件中想要使用C编译的函数/变量,就要告诉编译器,待使用的函数/变量是使用C方式编译的,即使用extern "C" {..}进行声明(注意是声明,不是定义),这样,编译器就会按照C的方式进行链接
Relevant Link:
http://freetoskey.blog.51cto.com/1355382/931085
http://blog.csdn.net/zhangjg_blog/article/details/28264737
0x2: 使用extern可能存在的问题
从最本质上来说,extern的作用是将本模块的变量或者函数暴露给外部的模块使用,从而达到模块间协作的目的,但是,使用extern这种机制来进行跨模块的变量/函数引用可能会出现"不一致性"的问题
. 在使用extern时候要严格对应声明时的格式
. 当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误
针对这个问题,通常的解决方案是: 只在头文件中做声明,真理总是这么简单
. 提供方在自己的xxx_pub.h中提供对外部接口的声明
int add(int x,int y); . 然后调用方include该头文件
#include xxx_pub.h . 从而省去extern这一步,以避免这种错误
0x3: dllexport、dllimport关键字
dllexport和dllimport存储类特性是C和C++语言的Microsoft专用扩展。可以使用它们从DLL中"导出"或向其中"导入"函数、数据和对象
__declspec( dllimport ) declarator
__declspec( dllexport ) declarator
特性
. 显式定义 DLL 到其客户端的接口,可以是可执行文件或另一个 DLL。 将函数声明为 dllexport 可消除对模块定义 (.def) 文件的需要,至少在有关导出函数的规范方面。 dllexport 特性可替换 __export 关键字。
. 如果将类标记为 declspec(dllexport),则类层次结构中类模板的任何专用化都将隐式标记为 declspec(dllexport)。 这意味着类模板将进行显式实例化,且必须定义类的成员。
. 函数的 dllexport 使用其修饰名公开该函数。 对于 C++ 函数,这包括名称重整。 对于 C 函数或声明为 extern "C"的函数,这包括基于调用约定的平台特定的修饰。 如果您不需要名称修饰,请使用 .def 文件(EXPORTS
关键字)
. 在声明 dllexport 或 dllimport 时,您必须使用扩展特性语法和 __declspec 关键字
Relevant Link:
http://msdn.microsoft.com/zh-cn/library/3y1sfaz2.aspx
0x4: __declspec关键字
用于指定存储类信息的扩展特性语法使用 __declspec 关键字,该关键字指定给定类型的实例将与下面所列的 Microsoft 专用存储类特性一起存储。 其他存储类修饰符的示例包括 static 和 extern 关键字。 但是,这些关键字是
C 和 C++ 语言的 ANSI 规范的一部分,并且本身不包含在扩展特性语法中。 扩展特性语法简化并标准化了 Microsoft 专用的 C 和 C ++ 语言扩展。
简单来说,__declspec关键字是一个类型修饰符,语法
__declspec ( extended-decl-modifier-seq )
extended-decl-modifier-seq:
. align( # )
. allocate(" segname ")
. appdomain
. code_seg(" segname ")
. deprecated
. dllimport: 声明导入DLL中的函数
. dllexport: 声明将DLL中的函数导出
. jitintrinsic
. naked
. noalias
. noinline
. noreturn
. nothrow
. novtable
. process
. property( {get=get_func_name | ,put= put_func_name})
. restrict
. safebuffers
. selectany
. thread
. uuid(" ComObjectGUID ")
示例
#define DllImport __declspec( dllimport )
#define DllExport __declspec( dllexport ) DllExport void func();
DllExport int i = ;
DllImport int j;
DllExport int n;
Relevant Link:
http://msdn.microsoft.com/zh-cn/library/dabb5z75.aspx
http://hi.baidu.com/baiyw920/item/35384a440b7b71ad61d7b9d6
0x5: __declspec(dllexport) & __declspec(dllimport)
. __declspec(dllexport)
声明一个导出函数,是说这个函数要从本DLL导出。要给别人用。一般用于dll中
省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类 . __declspec(dllimport)
声明一个导入函数,是说这个函数是从别的DLL导入。我要用。一般用于使用某个dll的exe中
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量
Relevant Link:
http://www.cnblogs.com/xd502djj/archive/2010/09/21/1832493.html
0x6: inline关键字
. inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高
. 很明显,类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。
. inline可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员
需要注意的是,内联函数一般只会用在函数内容非常简单的时候,这是因为,内联函数的代码会在任何调用它的地方展开,如果函数太复杂,代码膨胀带来的恶果很可能会大于效率的提高带来的益处。内联函数最重要的使用地方是用于类的存取函数
Relevant Link:
http://baike.baidu.com/item/inline
http://xinklabi.iteye.com/blog/676313
2. C/C++中的标识符
0x1: pragma comment
#pragma comment( comment-type ,["commentstring"] )
. comment-type
是一个预定义的标识符,指定注释的类型,应该是下一字符之一
) compiler:放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的 ) exestr:在以后的版本将被取消 ) lib:
放置一个库搜索记录到对象文件中,这个类型应该是和commentstring(指定你要Linker搜索的lib的名称和路径)这个库的名字放在Object文件的默认库搜索记录的后面,linker搜索这个库就像你在命令行输入这个命令一样。
你可以在一个源文件中设置多个库记录,它们在object文件中的顺序和在源文件中的顺序一样。如果默认库和附加库的次序是需要区别的,使用Z编译开关是防止默认库放到object模块
我们在使用一些特殊的API的时候,常常需要使用这条指令明确指出一些特定的库文件,否则会造成"无法解析的外部符号"这种错误 ) linker:
指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。只有下面的linker选项能被传给Linker.
4.1) /DEFAULTLIB:/DEFAULTLIB 选项将一个 library 添加到 LINK 在解析引用时搜索的库列表
4.2) /EXPORT:可以从程序导出函数,以便其他程序可以调用该函数。也可以导出数据。通常在 DLL 中定义导出
4.3) /INCLUDE:/INCLUDE 选项通知链接器将指定的符号添加到符号表。
4.4) /MANIFESTDEPENDENCY
4.5) /MERGE
4.6) /SECTION
. commentstring
是一个提供为comment-type提供附加信息的字符串
我们在编程中经常用到的是
#pragma comment(lib,"*.lib")这类的指令
#pragma comment(lib,"Ws2_32.lib")表示链接Ws2_32.lib这个库。和在工程设置里写上链入Ws2_32.lib的效果一样,不过这种方法写的 程序别人在使用你的代码的时候就不用再设置工程settings了
Relevant Link:
http://baike.baidu.com/view/3487831.htm
3. 编译选项MD(d)、MT(d)编译选项的区别
属性 -> C/C++ -> 代码生成 -> 运行库
它们之间的区别是
. /MD: "multithread - and DLL-specific version"
运行时库由操作系统提供一个DLL,程序里不集成。MD的意思是多线程DLL版本,定义了它后,编译器把MSVCRT.lib安置到OBJ文件中,它连接到DLL的方式是动态链接,实际上工作的库是MSVCR80.DLL . /MT: "multithread - static version"
运行时库由程序集成,程序不再需要操作系统提供运行时库DLL。MT的意思是多线程静态的版本,定义了它后,编译器把LIBCMT.lib安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号
0x1: MD、MT的选择原则
. 选择/MD、不选/MT
) 程序不需要静态链接运行时库,可以减小软件的大小
) 所有的模块都采用/MD,使用的是同一个堆,不存在A堆申请,B堆释放的问题 . 为什么选择/MT、不选择/MD
) 有些系统可能没有程序所需要版本的运行时库,程序必须把运行时库静态链接上 . 多个模块,必须选择相同类型的运行时库,不要混合使用 . 选择/MT需要解决的堆空间释放问题
不同的模块各自有一份C运行时库代码,各个C运行库会有各自的堆(C/C++的库向系统申请了一大块堆内存并进行管理,向程序员封装了一层堆的使用接口),导致了各个模块会有各自的堆。如果在A堆中申请空间,到B堆中释放就会有崩溃(bad address free error),在模块A申请的空间,必须在模块A中释放
Relevant Link:
http://www.cnblogs.com/cswuyg/archive/2012/02/03/2336424.html
http://blog.sina.com.cn/s/blog_6f7265cf0101nhs0.html
http://blog.csdn.net/nodeathphoenix/article/details/7550546
4. C++类模板、函数模板
类模板与函数模板的定义和使用类似。
有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面语句声明了一个类
class Compare_int
{
public :
Compare(int a,int b)
{
x=a;
y=b;
}
int max( )
{
return (x>y)?x:y;
}
int min( )
{
return (x<y)?x:y;
}
private :
int x,y;
};
其作用是对两个整数作比较,可以通过调用成员函数max和min得到两个整数中的大者和小者。
如果想对两个浮点数(float型)作比较,需要另外声明一个类
class Compare_float
{
public :
Compare(float a,float b)
{
x=a;y=b;
}
float max( )
{
return (x>y)?x:y;
}
float min( )
{
return (x<y)?x:y;
}
private :
float x,y;
}
显然这基本上是重复性的工作,应该有办法减少重复的工作。
C++在发展的后期增加了模板(template)的功能,提供了解决这类问题的途径。可以声明一个通用的类模板,它可以有一个或多个虚拟的类型参数,如对以上两个类可以综合写出以下的类模板
template <class numtype> //声明一个模板,虚拟类型名为numtype
class Compare //类模板名为Compare
{
public :
Compare(numtype a,numtype b)
{
x=a;y=b;
}
numtype max( )
{
return (x>y)?x:y;
}
numtype min( )
{
return (x<y)?x:y;
}
private :
numtype x,y;
};
将此类模板和前面第一个Compare_int类作一比较,可以看到有两处不同
. 声明类模板时要增加一行: template <class 类型参数名>
template意思是"模板",是声明类模板时必须写的关键字。在template后面的尖括号内的内容为模板的参数表列,关键字class表示其后面的是类型参数。在本例中numtype就是一个类型参数名。这个名宇是可以任意取的,只要是合法的标识符即可。这里取numtype只是表示"数据类型"的意思而已。此时,numtype并不是一个已存在的实际类型名,它只是一个虚拟类型参数名。在以后将被一个实际的类型名取代。 . 原有的类型名int换成虚拟类型参数名numtype。
在建立类对象时,如果将实际类型指定为int型,编译系统就会用int取代所有的numtype,如果指定为float型,就用float取代所有的numtype。这样就能实现"一类多用"
由于类模板包含类型参数,因此又称为参数化的类。如果说类是对象的抽象,对象是类的实例,则类模板是类的抽象,类是类模板的实例。利用类模板可以建立含各种数据类型的类
Relevant Link:
http://blog.csdn.net/oqqquzi1234567/article/details/43489291
5. C++修饰符
volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会,volatile的作用是
. 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值
. 编译器常常为了加快程序执行速度,使用寄存器作为运算的中间值存储介质,但是在多线程场景下,这有可能导致脏读、幻读的产生
. 强制编译器不进行任何优化,完全按照原始代码逻辑进行编译
Relevant Link:
http://baike.baidu.com/item/volatile
6. 调用约定
__cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容
. 函数参数的压栈顺序
. 由调用者还是被调用者把参数弹出栈
. 产生函数修饰名的方法
它们的定义如下
. __stdcall调用约定: 函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈
. _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式
//注意: 对于可变参数的成员函数,始终使用__cdecl的转换方式。
. __fastcall调用约定: 它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)
Relevant Link:
http://www.cppblog.com/mzty/archive/2007/04/20/22349.html
7. 错误处理
0x1: 错误处理函数返回值原则
. 如果函数的返回值类型是int类型,并且函数的返回值不可能是负数时,则返回0表示正常结束,返回-1表示出错
. 如果一个函数的返回值存在确定的"合法值域",那么就可以通过返回合法值域之外的值表示函数执行失败
. 如果函数的返回值类型是指针类型,则返回NULL表示失败,其他值表示正常结束
. 如果不考虑函数是否出错的情况(即该函数不可能失败或完全由自身处理失败的函数),则返回类型使用void //最佳实践: 数据和处理结果分离
. 用指针作为函数的形参将函数的结果返回给调用方,并定义一系列枚举值表示该函数处理逻辑本身是否成功
) 返回0: 表示成功
) 返回-: 表示失败
1. 返回非法只表示失败
long fsize(const char* path){
FILE* fp = fopen(path, "r");
if(!fp){
return -;
}
fseek(fp, , SEEK_END);
long size = ftell(fp);
fclose(fp); return size;
}
2. 返回空指针表示失败
const char* strmax(const char* a, const char* b){
return a && b ? (strcmp(a, b) > ? a : b) : NULL;
}
3. 返回-1表示失败
int mod(int a, int b, int* c){
if(b == )
return -;
*c = a % b;
return ;
}
0x2: 错误号
. 系统预定义的整型全局变量errno中存储了最近一次系统调用的错误编号
. 头文件errno.h中包含对errno全局变量的外部声明和各种错误号的宏定义
需要注意的是,不能根据错误号直接判断是否出错(而应该根据调用函数的返回值来判断)
. 虽然所有的错误号都不是零,但是因为在函数执行成功的情况下错误号全局变量errno不会被修改,所以不能用该变量的值为零或非零作为出错或没出错的判断依据
. 正确的做法
) 根据调用函数的返回值判断是否出错,在确定出错的前提下再根据errno的值判断具体出了什么错
同时,在多线程编程中,我们还需要注意错误号线程不安全(错误号errno是非线程安全的全局变量),errno是一个全局变量,其值随时可能发生变化,尤其在多线程应用中
0x3: 错误信息
将整数形式的错误号转换为有意义的字符串
#include <string.h>
char* strerror(int errnum);
实例代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h> int main(){
char* p = (char*)malloc(-);
if(!p){
fprintf(stderr, "malloc: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
scanf("%s", p);
printf("%s", p);
}
aaarticlea/png;base64,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" alt="" />
或者用perror简化代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h> int main(){
char* p = (char*)malloc(-);
if(!p){
//fprintf(stderr, "malloc: %s\n", strerror(errno));
perror("malloc");
exit(EXIT_FAILURE);
}
scanf("%s", p);
printf("%s", p);
}
判断函数的调用是否成功,必须依据函数的返回值,而确定出错的情况下,可以依据errno获取错误的原因
8. 环境表
0x1: 基本概念
. 环境变量表是进程的属性之一
. 环境表主要是指环境变量的集合,每个进程中都有一个环境表,用于记录与当前进程相关的环境变量信息
) PATH=/bin:/usr/bin:/usr/local/bin:.
) CPATH=.
) LIBRARY_PATH=.
) LD_LIBRARY_PATH=/usr/local/lib:.
) SHELL=/bin/bash
) LANGUAGE=zh_CN:en_US:en
. 环境表采用字符指针数组来表示: char* arr[4]
0x2: 环境变量表数据结构
环境变量表是一个以空指针结尾的的字符指针数组,其中每个指针指向一个格式为: "变量名=变量值"的字符串,该指针数组的起始地址保存在全局变量environ中
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h> //引用外部的全部环境变量
extern char** environ; int main(int argc, const char * argv[]) {
char** env = environ; while (*env) {
printf("%s\n",*env);
env++;
}
exit();
return ;
}
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABisAAAGZCAIAAAB3/5UeAAAgAElEQVR4nO3d24GrIBCA4fRkOxRDL9RCKfaxD1HkMgOYmE3A/3s5Z10FBu+zqI8HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjWaxfnbmurCdvl+rET9SOjXFSV0+PbQkAAAAAgP+1WP9iCuJIFyVZo2hydI8fTU2qEzMg30qLKBG9WtQR/uudfCEx6/JaV2trcyvxA2uPlBEAAAAAAEMTkyNyFqleyjPtsFi/LxGmPR7GHXWkuYSfykDFota/IIvgFzJQcqe+0tX62nw8jPPOpcHuwceLnfULWwQAAAAAAHe2WO+tdfIwpCwLkk00+1JpsinOvRi3TQ5LSxkpLVtjnDR7ko7py0DJte9TnYvmr8a+zblY773fJ0gDed7LP8WBK518TC6zNdnaLJ9NTOZK+lIfu5WuC6nrpMXTNSGtrHxtOpOn27bMk7wx9MmW7eyQovG1LblvP1J6HgAAAACA6S3Wl1mM7e46ugUXJ26/UJYuf1QehdIGqKijbl4bA6W2LHruqx37loFanQlpprK6cspife94MGHEU2UMVPG4Xp7ZEAKJGiOuknJi2gCx6+TF456Qckjx2tzGvx115dm3F7M2We/1d0jc4DIDV/RQx37U6nkAAAAAAGZV3AiLt+DafXmZHMmGinjfykBV8k/ii6DSAl7OQIlpkp7YtzFQ0bAcoQvErEzc9D25EsaN2VpSrfYUXjJ7dW2GcrQUkRpB+vOpxY//x9uNsDZDjEW2S+rjE/TGNzvkaLIwiqrMQJ3ejxgFBQAAAAC4jeLWPp4Qp2aUh5Oy5aPkzP5ep2oGSrkNrzzFlg67eScD1RlmObGagepJLBwJpy0TJTztlTVdGlNVDgyS1mY2iug5eEtam0qZUvrlxOLbHPr4tzV7yC6J4UgRvZGAkp/Aa3fIsXC+UlqjxB6n9yMAAAAAAOYm5ixeHwOVZ6CKkS/JfbueKqrdm2cPR/3UGKh30wpyqqX2qGM+BkrPg4gTtdgbWa1W1+U5SqM+c/bsxPKBu+1NW28+g/dGh6Sta4x46t+PyEABAAAAAG5JHl5z6j1Q2cfMshc2r2oGKnvO7pgnvzFPvoKWztD5HiNhqvgyo3bs1QyUGFEoo+O1P5UhYcpDYOmQMCG/ko3pUVNmWpnyQ4FF16lNCpvCkY5R12YRw9bDnW8hLztZ6s/eDjla4IrqOzJQ2nugyEABAAAAAG5JGhMSskdCHqEciBKGr4gZqmyeaNZy2IswFuZ4MquYlhWdZx7SJtUKfelbeFIGSowoKqGZRdEzLVknRz+76nilrPOqI3HEMuUmSV2nNEkIvrI209YdHdz1zu6ik5X+7O2QI6yjFGVb6tyPyEABAAAAAHCVzuE+P6Q/F9A5GOc1b7zs6FOuaZLyDqhP+8H+BAAAAAAAVzpGioyQimploBbrwlN25DRO+1ICCgAAAAAA4Je0E0v781Tkn056piLJPwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUDIuebWRcevqXPS5+fS1R8frxeuvQ4o+dr/NmX3CPv44fdfEeFJce/HCc+OStw7VPl0nlWnU2BuL19oEAAAAAABwc9F3yrb3ccev5TYuye2ElMpirZpdSV/rvVjvjPKqb2lOeWKYP07qxJ9Y25d6pn/i9jfSQOkcSuySxXohpMX6qATLe8sBAAAAAAAej5BpCRmVNAUUpXb6hvSIyaY3Jx6/i9oQJ6BCQsi41TsXJ9VezkA1PpEnZqC6ewkAAAAAAOBmtufG0qFQmy3PU03GJBbryyfYxMXFOcWJRylqtmj75XNi+NV7Gag0xyW1PnvebrHeW8tTeAAAAAAAAKXk7UmVzM4xcz29Er1OSXwPVPJgXe1NSmkuqjsDFQYovZeBev4ye+GTFPv+wF7Sj8kDeQAAAAAAAPdm3OqtDbmXnjFQvU+b7VmY9hAqMV+TTezPQEU/fmoMlFRM9mQez+QBAAAAAAA8Ho8ozRK98an5Hqj+3EoxhKoxZ21i53ugokSaveA9UB1joEIxxpGBAgAAAAAAyMSjjLb/93wLr5JbSb5eVx0DJc4pTpRrjX8rpM+2zNGHvoWX5JqOWaPieAoPAAAAAADgsSVpsmFF3kdDftIMivZ+plz81qeQmBEHEZVzyhPTcUjSG6Ok16gnr2WSg8/KjKtuZY/EtieTGQAFAAAAAAAAAAAAAAAAAAAAAAAAAPeVP1n3q0+ejdJOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwJ8IbkrxdsqneLuWsz7coGRe9UCn5od9i/bMGAAAAAAAATMy4NcoCpT9JExfrV2+XLS21Z6O892SgAAAAAAAAIDqbgXo8jFudeRi3eue8M4+Hcd5ap2egFuvT4VLPxeXP0y3WJwOw9one2mgR7/26rqtzLpsTAAAAAAAAP+eNMVDeGuudMe75+F5tDNRin2Ok0vLLMVDR7/dF9v8fC26/SVpCCgoAAAAAAOBnFRko5ZVP6auh9uUW6713zzSQM8f4JXVsU5IryjNQcdIp+a38iy3rxbN8AAAAAAAAv+3kGKjtIbowMRrc1HoPVFg0kDJQYgIrnZEMFAAAAAAAwFBOvwdq+0l6OVRlDNRi/eqsTd9XLmSg5FwSGSgAAAAAAICBvfQm8tUZ8fXkmvAUXfE4XbZUUqpxUf6KDBQAAAAAAMCoqu+BSh64CxbrV+99dwYqefwu+TDeUZ/wLTz5lVAPMlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEjtq3aL9frX9l4s8/OLAwAAAAAA3N1i/bp75lmMS9I8zx+NW2PinPH8rzTDmcel6Z6ryiQDBQAAAAAA8Abj1ii5slj/TDaJGagyC3NdBuoo/rp0z2VlkoECAAAAAAB4XU9e6T8yUNEyi/XeWheNtNonP0dfHWXHc9Ybp5R5jOuSKjqmNioCAAAAAABAxWJ9mVP59wxUMsZosX5PMxV1pu+BiuYsXxDVXWa6eFLQYp1dWhUBAAAAAACgKXrDU3i7U6Z8D1RI5/RloOKXTSUlbAtkY5D23+VFlRmoaM4ksdRfZjr7Yn2ZoapVBAAAAAAAgBP27Ms/j4HK5o8HL+WVFhkobc6+MpO8WJjhmJo8hac0CQAAAAAAAKeEZNPVGSh9DFTxlu9TY6DkxFBfmc2RTfHAKDJQAAAAAAAAL3p+/O744d/HQJXFnnoPlJgY6iwzKsy4NSSbXDwWKuSqyEABAAAAAAC8Ln7Bk/h2p5CBKocw9bwxKnnlk1B5/kv5u3VS9UpiqLvMo1DnxEfzkk/pkYECAAAAAAAYUPG03I+WCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADILNavu/AVuXKicaszx1LZj7VSvV20+eNqoopWeeJRgHGrM9mMSftVxslRVoOJ5oxrUBY/JtcKLVufzJ20s79Jcu35yugotKOXjgj2yeKcSjvrlYttb6wjAAAAAADws4yLMwOL9c7IE89koBbrowKMKxfP2xD9Lq38mBjnMJIlxAW0mrxzfpt7C7ZssGqx/phLWTxqTX/DkoLzdp5ZUqrduKTRlfUmzamEmfSYsXZp9GceoRhJufj5dQQAAAAAAH6Plu4RJ/ZmoKTfvZ+B8s6F7MlrGSjjVmeUVEhrTNfj8ailUcLiSTnttEtYOksjqe2sN6lde2+T5DnlMCX5DP31iovrEwEAAAAAwO9brC8fjxIn9megxGTDBRkou0TDes5noLbhNHIqpK8MNY0SFi+HJHXlteK5qu2sN6ldu3G9D7NJc6Zh2uIpPGFOsZ09lXcmRgEAAAAAwCCiNxLFj85lExvvLUrLezMDVdaylbnnMfQMVPpmqaOEkAFRhvZ05WX08VPR4Cxvl8X655SepEmagKq2s9UktfbQK80oK3OmYaZvf0qbKvTnmQyUuDr6c2cAAAAAAOCniW/a2Sf2j4F6PwNVGf/ynPf0GKhjgSIVcuL9QlIaJV38/BiotPWVdnY0qW8MVPcji9nLwDrDlPuzOwNV3QgBAAAAAMAMKq/f+f57oJ4TjVu9tSfHQJUDuKLBQf2pjY7s1cn3QGVP4Knt7GxSR+39L1NKsmFFmHIGSu3PvgwU6ScAAAAAAKYUfWvsuNUXJ379W3jxV9iSp8TOvR8oSoXoqY3wIJu6rLq4+i08qczKp+nylE1Xk6Tak2RRNZsjz6mGWTyFVyu8IwNF+gkAAAAAgInF425ChqOceCYD9UjGIu1vbhJez5SOWJJfOOXMI0vmJG8hej0DJVYUtT6JL515e8uSvPgRVP41uDyFVGt5OwNVNkmpPenl3rUWrXc5zOgX9Tnldha09S7XDgAAAAAAAAAAAAAAAAAAAAAAAAC/r3yyjgelAAAAAAAAAAAAAAAAAAAAAAAAAAD4Pec+iAcAAAAAAID/tFgf3uEUkjjlROOSNzxlPz6S3+S8tdrEqBDj+l4itVhfzvdmBkoss5jlXA1JmUeH8p4sAAAAAABwN2nmZrHeGXlidwZKLlmeGCWdOnJAlXLfzED1LH02AxWXGf2fwVoAAAAAAOBuetJEYeL1GahjQndiJq14H1rkXLz8MeBIzvvkjY9+XqwPI7biBJL0ub9ooFi9v5L6To+lAgAAAAAAGNtifZk+ESd+KAP1HPvkevNPafrmGDdlnJhtSmaQE0JZmYv167FI3Kg8c5Q9ZOeS9udlZgO/eBIPAAAAAADcTDTC50iUFBPL1ztdk4HaShZemCRUVDweGH4XfpM+zXckf468T5lL08tMh1sVGSgtbVYMufJ2Cbkt41ZvxcUAAAAAAACmJ+ZU9omfGgPVVZY8Y5wTSjJQYgJrX7geiFhm8ZtjkvgUXm2QFWOgAAAAAADAzYnJkefE/8pA6WOgihSQNgZKGZkkxdEqszarFlY5I++BAgAAAAAAd7Z9/C78sHq7yBO/PgZKWLT5HqjHw7jkGT7nkrrk11Kp74HKRjaFVz8lv1IeNORbeAAAAAAA4MbiFzzFaZRs4rczUPJMrW/hFd+8W7MEVF6m+C28eHH5W3hpmksI5piXJ/AAAAAAAAB+0iceXRPLfLMiHrEDAAAAAABAAykkAAAAAACAXxI/qic8yTckMlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOCfGLfGrz0ybnuN02J9eLHTc4bspU/ixA+/Aop3NAEAAAAAAAxIzkClUxfrncnnFBZfrBdmuRAZKAAAAAAAgAGJGah2sqm6uGqx3lvrklFUYbBVXE45Mf/s3tgf3AMAAAAAALgTMYW0WL8W6aYLxkCV5S7Wb8mkqCRx4vYLxkABAAAAAACMRh3EFA06qrzyKZm4FRS/QiodsXSkljbxhOQVVMXEfXYyUAAAAAAAAKNpP0a3j2xqjoEyrvVwXJFBiieEosSJ8vIAAAAAAAD4fT0vcup+OdTzp+oYqCIDxRgoAAAAAACA2SU5pO2H58fvNt1joB7NYVBlBun0e6B4BTkAAAAAAMCA4jFLIb8Tv+BJeOXTPjVPS9VfRi6NYer8Fl7eLBJRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDBSd8E/OXP9R3fP9S/XDgY6UOL32jET6/3eeR73M9rbp/DRXShO8cOAABwnZ+4JcJ7TtyqD7m+jZPvmI+425FH84ZZjdsnbcVrFYlzxsJSZ5r0nqOm3mzCi3dQQkVhUrs8qd+jBnWU8NaN30caX2wNZ5pzIhZxFZ9f72/J1lF37WLX1TaGa12+3uMdu7v5v7LHdTf+sgzUtzab97qu7s6x97oy9jON/2rsZeOzy4N2/I+s677Z+HRq31kmXe//dpz/QONP9fxbl9OfbPzHrw7ev64r5ny/8b2r4wM7bHXita6/pj3b88Z1zfaBm80Pxt7ZVGL/hmFiv/V677lCfvsW+J9jfzweWmIoDXexXu+lxfpo3md/xiNB9qLkipQ50wuucmq9SW+Kauq+zX3pfrhSUce2ZFzaS3F/GOed69ga38hAfaLxybZk7LmWndn9xMa/st7fkK2j7trFrqttDFc3+/L1/tKZ5Vf2uO7GX5SB+tZm817Xtdw59j6Xxn783Gz8V2NvrqOuJohnw281/uxZJm38vx3nP9H4o7gPZ6A+0PjogjO94r3cFdd1H2h83+r44A7bH/vLrr88ONHz26zPO6i4LG3ua7viczcjHYsTe2/slxso9luv96szUF+NPWtIeRVz4u5OWj5t0tYgsSJtzrj254LnbjgX6721Ls7Rdf/tMGloozf3Qp07mhcqal0d1io6u7Ml8xu3OtN5ql+LWvdue72XXm28OkyumNv7vdePhr7b+O71HlcUzdS93o8mRLWc2erytuRz1heXd4Te9PUn1vuZ5aQ9bozGK5uNHFE1gm9sNu93nfAnl7vELm+fwklK9ZnYuy413otdONrEi505rQvV9SyunA1fbPzj5EabV3dyxVVP5a3FhT3uGI9y5mB3beO7Fkw4IyzUu+l8oOdbFyr5/v5+45tNuqzxwjYvrI4uV+6wvbEfzU+ux6O/cuvN/9gFuVS+0oCOLlZWh7Jrd55lPhh73+JvxS4dk9NZay0YJPZTq9h03QgNE/uJbX7C9b7Nmx8QizC/fP/+2uJqYuiFM2RUZjwxpJCaqS4h2bRsfznob5IYQJLqWqyr3qCXTYpKjYI4CjX5+OAlywueq0js17z2WHxiXZ651bwEcfEyA7XP0wjgE41PD6R5WjVM2Fq2bxghhDcb37/eox+LC6qO9b7Nlq6jE1tdTLygSicKjS93hGRLru1lH9loo4vebOauPW6QxsubTeUYIgbwvc3mva6LV80+uvEmsWvb56mz7Edibzf+zdjFo0282Lm/dWVxFQdbIXblbPhy489ttEXjz604tfFJmcri0h6XxtqbSbi48Z1H2uqm1x/AB3pev2rKWhZmfLfxlSZd23j9OvnsbcmlO2xv7OKJ9fh//WjzqQtyoXHa4vttZXvbqKyOtJf7zjKfjL1z8Tdirx+T9zuFzuJ+O/ajjI5V3N5nh4q9e5s/ps2z3tVjVxRmVEXjDPPPsdeoefkox1YpT+yX9zNQeXJPblJy85esSvFUJ/ZqsfizSaHH4xZWztZ5P2Rn8pMV9W4EoWDhlqHjSkU8KeYR/V/jjYt+SFdYvPhe+rZBxQG/0/iX17t+aaltn8I66q9d7Dp1otj4Yo+VIvrPjTbSnT5LMo8DNr48UdQ32u9uNm92nXg+vGHsyeEi75T/jb2v8RfELh1tigxU/VQu73HlRlXErp4N32l890Yrn+O6V5zS+P7jfPW69juNf4hTxIuTbLbotH+c/v+/8UJyoWN/f7fxZ67r3m68eqNT5E/+aYftjT0tP5l5a1R8p1Y0/rOXB62e31tvnOt54kNauVFVaeTts8wnY+9Y/L3YxctC6ZcTxP4QwlSP9dlONHrs3dt8VPQssWuzJOu+/+Lkn2NvBFa9UKmdlB5Kv7yfgYqvUIXFqk3aZhCvHZ/OLFrpH+lKOq6s3a96RefXYnRp019CmYFSI/p84zt7Prqac0a5PHmh8f+23sV11F97XlQZqDgxbX+2I3x3vZeTT/X8TRr/3c3mza4T57hh7PmFY88W98HYT6+4F3aZd4421cb3XbWpZ8PvNP7Eimueys9stGVAreugzzW+c7sX7jO9XRbr/PPfzsP1tY1vXnlWj/MvN/7Edd17jX+o18knz4+P63bY7tjLm61oFct3Etnin7o86Ov5bcmuQ7m4W0m7dl/DP3lp1L/4i7FXjsnttT5S7GdX8X+c3w//vt4rp7O51vtWQ1liFuZv3ApdnoHqPVsf0tvwrUFiIdqcUQRyT5rmH5H0TqhnB9OG1gqSMo5iYC9UdPp8H5J3mXopHRmo/2v8I30d2xUZqDONf3W9F3/Yaqx3eR111y53XcdEcdnQdUVE/7jeuxsv7nGDNv75Xymin9xs3uu69DgvTLxJ7NUm/3/sHQtet8tUs676qVxpi7hFlfMLXfd24zs3Wrnx3Suu51TeebQRJ36v8S9moB7Grc5aZxfjnDH7n43+sfH9GZxyf3+v8f3XdW82PitKX2v/t8P2x66v1MX61dnQgv+9PDjf8x2kk4d4M9J3lvnkpdH53GVDb+xFx48de/cqFmsfO3axwJus91C+kH5LJ335/v21xbXEUNK8RjYt+vXxLbx92t4T8tWSMmeZzjzTJKETokfam6fCqP7iJCyNo3uUacCu861ekbgWs9qTdI3QIeKZJ29S1kxpC/7PxkfbSBpRvPiZDNSpxveu9+jHop6u9R7PLTW5WrvYdZWNoWi8tCMkW3L98HH9ek8mmurLTcQ9bpDGy5tN5Rii+sJm82bXpcu89B6ocWPXts/TJ/rLYj/R+Pdil482ySG3tt71xsvHWfEcpzT11cZ3b7T6Oa7v6kJq6osb7b7HpevgvxuvTxEXL1bx81p6u3yu/Yn7I43Xrzm79vd3Gy816QON16+TO69oP7fDChOr2/wjjC4Idbdi+MA1bf9mo+vZO9Rdu/cs87mbkc79XdZ9ZKhcFjaNEfv5Vdyz7seIPUxrb/PTrfdjohK8WOs37t/VxWvKvzAcu3I6Rbccaba4A9KltYrEOYvzzPOeobtJWh/2xRPNW14CCRdFq/4JhkZlUkVpAel0sXK5ms4rlb22/QzdvQV/pvHR8vnudmUGSlnFfet9sV74qNmp9R6XlF4Il8v2dZ26MRTrXd4RwtT2weP69a7u2V173CCNlzcbJaJWDB/fbIrFz3WdcLSRFr9J7PL2efJMfWns/dv8m7GLR5swsbne9dOEtJjQ+KMc7VB9tvH9G63S+N4VJza+/zgvVhRC/0rjzxwuksYKmYR/bnzl9N63v7/d+KJJn2m8fp2cr44zjX9vh9UmVrf5+P4izNO6Dbz68uDUZlNtVHPvUHbt/rPMB67nz+3vr8cuHJOTBjWvDMeI/ewq7lv3Y8Selqtv8zOu97TgcBYpwvz6/bu2OCbQ3qJ+2NCNz52+c3zL0F1H47/lzcYT+4Xt+U/E/q/1XXeRRc9/C43/Fho/qN+N/dJjslbDj8ZeuPxOZaDYL0fs324FgMd/Z6AAAD8iPKjEZRkAfB3HZBG9gWmUD9Exzgq3RAYKAG5qH4HOWQAAvo9jcmy/W6c3AAAAAAAAAAAAAAAAAAD4Vccb0Rnvp6OX7i18Bgf4AbweYHCcUKZy58e6if3brfiOO8d+Q/VLDjaGGbFW8S7j+m6c/+mWRvh84EvfYX/pM+6Px6O7Q+R9761eGjz2twwT+wfMF/sIEWXfOm2UPEJE6dwvHYhGC/NF44R5jxPKe0YI88wps/zafM+8c8TebOjvhrkXmxRI7D0VzLfN78W+sfKHCTPMfV0GarTYr0TsxJ5PmjL2xXpn9lqNazXyXzJQUSV5fR1HsDiIfExKx+LnOuTyDNTwsb9hoNgvN1/s40W0WF/db8eL6KUD0XhhvmSkMO9xQnnHGGH2nzK3IvcGVZeaLXa1oSOEKRZI7NUK0nr2Vk6wzfcWWGnoMGGWLZaL7O6L8WK/DrHn/91bRuy1pceM/fj4XTv3lXdL+uE8b5fFeu/9uq6rcy5JvB2zNkIzLmpI1nFnj+YvLd7XIfk3A6N5m71UK3Tc2Bfrj8WMe/5/utiViEKmOYvBuom2+QnXZlxq86J3kIj2bdG5cCCaccXdJMzHDU4oNzl3yGeEZphJdFLVE8ce1zJCmOKlEbHfc5uXr5OnW+8P8VwcTQ1RTnhJ/EijCnfBaZj6fbFS9SCxS9/iU+70i15SS/z92MuStku0G8Qeyus4gGkLZqXv1XbcqakZ7v3+bUu97T9K8+fZubKkbHOOZhb6UYoojqyRCHyvQ+T12uylzuLGi31ft0IPTBV7KCItNt20oyoagxhmiL34/VgRNYeZDBPRsREaV54fpllxNwlzn3X+E8oNzh2NM4IS5qlhBZPFrjXlZ8MUCyT2e27zWoFRuVOsd/lcHK3DfYY5L4kX69MrkDLMjvtitX0/HbtSZig4ux1qpisGiT1PkKehFhOmiv0h7tq98lq35Y1zpn0Tph42jlbsgW69J26beyHL8dDiLrQitDOtsa8fQ8F5z3Qsfq5D5H2v2UsTx77VL1U1UewPec8rDzv7T/vRZL7Yp4gomWfsiLKtTk+REuYAYSoBzhnm9OcO6Ywg/jJyXEreJPaxwxQLJPaO2COzbPNagUXsY4cpnouLa+EoEbPPOcklcbEVl2HuVWb3xePHrpQZYk8vq+PWDB17tD7j9XqL2OVd+01vvRI1Trcpe9oj6/RKk7OAmonARnOTqvoXv/5N5HlSsqO4EWMXA50udiUifde89o8erZZ9I/bUUBG9cpr92YgqW91MK+4mYYYabnBCeUx/7ji90S628WjwxLHriz9+OEyxQGIPld9qm68UONN6F1dxeZMdJWKSOZtlPn44drG8Mkz9vrhd3k/HLpSp3On31TxK7M+yFuu8j1bvbWIvd+1/Uh41svOFtqdlWWFvFy0RmHZ8uXGfy7e9tRbbejNQxVl11tgX61dn80TMZLGr10hFBqrzDz4jxz58RMXeOnZE0pF2nz7RirtJmKH8e5xQJj93SGeEfbp8LlWv7OeNfewwxQKJvaz6Dtu8VuBk6108F+u3B7NdEosZqCxM5b54/NiLMrULM/HAMHDsxq3OWmcX45w5VusdYn+rrKUcuHVmzvQWu/y5JwOVZ+cK0brLL72Vo3nUhuQd7sL5rLF4hTRnEb84VZ5LNHbsYdLxu/lir0SU/ipasDnKZvzYB42o52+RY0V0rKPoSDvfirtJmGHi7CeUO5w75DOCGGZxk6qbLnbZGGGGafn+Suz32+bDNPlI1zZImOK5OG3xc+LoqqwAACAASURBVGTFhJfEUnllmPssXWOgRoq9KDPautM7/VbMR/OHiH2x/sgbrfmly9yxS7t2r7e3NhO/qmpJU3m+NtpwXzD7XIJe91FNurwwvTjAl/Npi7/bIUdYRpiq9NKcsSet2ZaYL3Y5orSa9dj4+z78MXTsI0eUr7d6KSNEFNV0HGnnW3H3CTMpeNYTym3OHeUZQQxTOp/cJfahw8zL3XdYYm/GPt82r3XIfOu9PBdn9T/nnu+SOES15BOKb+GdyECNE7sQv3Kn35uFGSX2kG6Kkz03iV3YtW+rmUqfGLF/uxVV/YedkwaI/SQiGtRPhGmqX+6+qIbvh/l5hDm9m8R+kzBFd45ddJMOuUmYot+K/WNX/qKvx/6/4Sa+HvsX3Tl2AC1fPDADs1usC+MP2c8AAMCX3ezKnwswAPgxNzsPAf9rHwnMXgYAAL7uLlf++/NdtwgWAAAAAAAAAAAAAAAAAAAAuK3wCQtgGHcZ1y+5c+zd5MPaPM+pshFk6BDgPtjfb23283sf4UuBYdKZb2sKX2Xt7ELjvnXzSOzEnk8i9r6lR4xdNEKH5N+0fuFrqSOEeYGbhCm6PPZz3xh/zL9r/0KHdH4kcoTYP3UDNkLsWtXvdsiwsV+A2AeI/QM7/TCxC1Wzv79umNjPrOdhzu/XiN54n7/8vqPXjDvmyPN5HYsv1juzr8W4rP9B7Pl/95YRe21pYt9mHyx20YAd8sply4BhvuImYYo+EHv/lnaTXfsHOkT+u2lujNg/k4EaI3Zt6fc6ZODY30bs+X/3lv1U7Jfv9APFLizN/v6qgWI/sZ4HOL8XTZGSVov13lrXymcl+basCWdb9NLiR/PrvS7k7G4TuxjRTWLXwywXPyZWGzBK7Om4l1CumOjuzX6PEvtDWMXxph3VFOZLCpywQ6IltnKVLUReZpQwyyPYjGGWH5xRNu+wJTtX/zzyJ2I/tdwHYhcP6fN1iBSRdFiLLoIae8IgsZfrfbHee793xhGkuoWIVY8ZuzhR6xC16mFjfxQ7wn1iv8l6z4dy7/NKB0Dlyl8sdITYn0Hucxi3rs7cZb3fOXZlmx/8/K4UlLaqYyBVVmk6/ktoUbIhZbbt6uzi+wpqbsDRWDOXxzVz7GFhJaLZY4/KiA5hoQpjjzNWfPWuljte7Iv1QmhivHk+vCxpkNiFVRyVVoSZrfEJOyQuopg13kKUhYYJs3IEmynMokx580625FrwH4k9uSQqM7wfjl3sh/k6pBKRtLNXT25yeD8be7net+j2PT1sAbWD/yyxn+qQ+WIvd4T7xH6T9S63p3FIbxzwRop9D6VyWJt2vd85dqk9e6EDnN97JSssjyMpPlRi9j81rOnGcSKSULDQk63Ft0YaF5qihNa69Zg5dimiO8VehCl2Rjrx2YY5Yk8ii38Ixx1p4tixN1dxeswVVv9kHVLtmXja+GGqx7q5wizK7Nm1vV2+EftefbaL/WPsYf75OkSKSPqdPG2q2J0Jjdu2gtDW3zikfzb2Mx0yf+zPQO4Z+6zrXWxP7QCYTJwg9r2qMuk6/3q/c+xCe/IukKf9ROx1SROTa7q++5lTubSaPH/dv3jX27yOONML1zvErm5U88cuhClWUO6pWtnjxL7XoLQvTsmVE0WjxK6tYjXM4rA9WYdEdeRl9pwsRgpTKW+2MIsyf3jXFstUlrw09vKQPl+H9B/W9Gm1Mot2/nTsyk3IXdZ7f4c0yyzaSez1RiUREHs5+aKDv5CBknZt5QanVdxvx/7ILmTutN4fN4795QxUV3Ffir1obnJiFnZzIZeW1pMtczKSNzviTC3HFepNYi/Ku0nsYpjiLirVOnbsz+LW6np3yh/QRo9dW8Vl7OIC83VIKFH4S8ZE+7tW3oRhFmX27NreLt+IvTbxVV2xl42er0PUU/lD2uGlQ900sbsrxkCNG7s4UemQ+WPX70jnj33W9S62p3mRP8dxfm/P6uwR283W+51jfy0D9fOxR81Nc1m9zYiueYTLn7yIJR3NlbwCPr9LaC/eiCvp4/DqpyPim8QulneT2JUw4xZL74FqpKbHiL2Vhsn+XFRMlA0Su7SKo3mKMLO+mrBDHsIGIW4hsnHCLMubMsyiTHnzTrbk+qZ8fezJRFMdlK57PXbxkD5fh1Qial+hasaIvVzvyk1I9eA/S+ynOmS+2Msd4T6x32S9h2nKZcxxAFRvcATDxB6CSv5zj/V+59jVk/Yg5/dmU7bUWPJpmNbay1oXkmtZocL0Yrsq59MWf2MtRhUJzZw7djGim8Suh1nUIm8jw8aeVHPVt/AGiV1s52K98AGdtO545tk6REy7SVvI2GEWR7A5wyxClTfvo02tT799JPZ46XLuj8cuHtLn6xAhIuWw9ui9Qh0j9nK9azch6hYyUeynOmS+2B/FjnCf2G+y3vNm7b+RDunKlf+4sScVb7+8y3q/c+xZwc/fDHV+/x3Nvz5NjNi/3YrvIPZvt2LXn1z9mN/qkI8hzP9RZmEaQzuuuy4YLHbRXB2yNeIbl34/EXvdxw7+X4v9zqez/z3WaTX8UOz/uzH87v4+8Xr/Ab8VO9v8f7lz7ABwhR+4ZAcuZDpGr4YH0Ce7jOiJXTRfh8wX0fXmO/jPF1G/mx3rEj+Qgfo1t1jvyNx7mwcAjIMzFiaxj3fOnkCRN+99xPQkG/+p2EWTdchjxoiuNt/Bf76I+t3lWCchAyW4wXpH5u7bPAAAAAAAAAAAAAAAAABgYvI72cXhkoyhBAAAmBAPTWToEACIcVREYFzv1wO7txnxWwWdHzAQPh8YJp35wG6Y+dxnuh/dHfIBxH7P2EV37hBiJ/Z8ErH3LT1i7KKBOySq6bUSho39gluLYWPX2kOHvG7W2I1r1z1B7D1hiiaIXSmVDnm8+krHMWPvjnXsMF+wWO/MXqtxjfad2GbEcVHyYKlc9JmD/IsHHQ2Igwj19Tf8XIdcjtjz/+4tmzt20Z07hNjz/+4tI/ba0sS+zT5Y7KKBO2Rbeq/7fHeOHft7m8/AsWtF0iGvmjV247xzjXZMEHtPmMqCw8eutYwOeZyqfPzYOysbPczX7F+cqf+p7pgrmTdk2KJlxaxbfyouGSeV9d/ZU/k+/6nl+jpksd5b69Jo4olxjHv0ztU/IjpI7GKyNdtnQijEnsSe7kijd8hivfd+D/EI6CY7gngQ2H6RLb5Yf/xgXKXcEWLX1vtD/JONsnfIVQ8bu7YxzLTNn4092hHKLWTmDpEDudGOsP8vTJ0rdqHAEGCxzZd7R9dmE5f8+x2yl57v7cX+Pl/sp4+KW1itdowcexRBVOVcB4EL1vtcHbLNVrsVkm+WG60YJXbp2kbJnCi1jBCmdnPX266i9L3a9ugkJZqQb2tMkyfW60j3SaEBUkTRwiERqGwCL3dItOCxz0UTo1iP/zbGX44Ue5hhse44moap+/+JXYt9afxpfIgO2ULcY0kvwu+xIwg3l8n/bXLn/fz7wvCxa+s9XcVxhxR7x3SxyxvDXNv8udjFfrhHh2SlRDcct9gRvF2KE9xUsZchCEf3fVK5d/RsNqN1iHLwL/b3+WI/eVR8PJbncIPG3eHQsSthTnUQuGK9T9UhakTSkUHtpXFjV69tGnv6WGHKN3ed8lq3EoxzprUZPNR+lJohNi2dmPRNCNzsfydZ8/O53AChH0PBYt+EdSMu3t0hcSxJojeaeByP8onjxy799thnyiMPsScLxb8cuEP2dmwxh2bdaEeoHgSE+df4T2Wjxt653oVrq2OJW8Q+2Tb/cuxh3pt0iFbLTXYE71x5mpwp9iT6qBd6tvnnbFLXDd0hvQfA+WI/eTZMdpQjZTFX7FKYaT+MfxB4e73P1iFKRF1HhjDjuLFL1zZiI2cN83XvvYk8Pevq0+SJ9TqaicAaI/+RNS1TWfJMO+N77M6JzTKLdv5Q7I94H5JaHB9liP1RxJ4eCtRafr9DajchN9gRmmGKramXOkTsp9Z7XGW96vlin2ybPxt7eZl1kw45fp3Ve48dYV29Ly6PZ4o9NGWxzvsjr9K5zTc2G6kipfE/1yGhQO3IMF/s586GR32N9g8duxrmRAeBa9b7RB2SFVS/FZrsSuBRi6irkeOH+XHXZqDkRGDaSWXu8Fy8Yo93rIY2La0rX4jnKcOxY88KLI6mybGW2LM5i7uSgTvk9B3pXBuDdhBQil6sX50Nvx449trNZ9Eh0U9JJ90h9sm2+bOxl42+SYdsvxMuz26xI+zTsyrmiX0vxVpnF+OcqeVTyr1D6bqxO6TzADhf7KeOisblYXpr5otdCnOJ6pzhIPD2ep+tQ9KS1Fsh8cjgzGP02LU7PqnNY4f5egZqKQdunZhTubd6MQOliYLK4xNWQ9bO5B3u+yVgMtFUh6LpsjmjH49WyuvmCFvJTI4X+/76o2KVGrc6F23mxJ7F3rcP7OX9eoecykDNuDEIB4Hs/7bYXFqbwACxqzfeySpOmprvHdPFLm8Mc23z52JPw9j+uHaPDgk1ilFNvyNsNRU5qGliDz/vtw7hN8I2X+4d6mYzfIe0D4DzxX7yqFhr/zSxV8Kc5iBw1XqfpkPUiKQjQ6uXBoxdvbbpvOsbI0z55q7TmxvWIyRyj37OE3nH4i9moPZTe1pgWlU6PSnzWDiaL166nPvl1SB+C09YN3ubWl//GST2pKKsgPhijNiL2JNWNr8k8PMd0r4JmXpHEA8CcuOTJrYq/PnYK9edofp8/RZ7x2SxaxvDTNv82djFg+UdOkS/MrrJjnAc/JOSZ4k9THDmcVzvF/U/5y73jo779hE7RD74Z/v7fLGfPioeZbRu34aNvRbmLAeBy9b7LB1Siag8MrR6acjY1WubLHMycpjazd09fa0HOs4eAnPlg2CDrX1i/3ANt+2QwQ4ClxpsvV/qt2JvbgxzbPMizoZfRezfbsUP+d0OudtV0P9eHvxW7P/rt2LnsvCrfiL2zzfiJ8LE15w5yoQnt2640RD745axi2brkB+41MCvUDaG2bZ5EWdDAJL77u9cHtwT6x23O9jhn507yuzj4+64URL7PWMXzdUhXGogUDeGubZ5EWdDALK77u9cHtwT6x1koAAAAAAAAAAAAAAAAAAAmNpdh0ff1bzDg+Mt+fgkxKTBvip8u2ke3ev9zrFPbvLY9/H8k4fZ5+5XLDzcgTu5+/4OYCd8KVD99HZt6TBz8vXAnjKM+9ZNxJSxd36bZMrYaw2dNszXXtcyQIdIW/JbF+sDxX65gWK/83q/c+zywn2xjxZmFtesYXa5/RVLe+3PG3sbsU8W++339zZiJ/Z80pyxR+e+/DTYcWNr3DFH+HN0/w3xYr0ze8xxWf9jztj7hgXMGbvQ0BuEeSYDNVKHiFvyG3fjI8V+tZFiv/N6v3PsrQD65hokzJcyUOOF2Vnwza9YWmt/5thbiD3/796yUWNnf28h9vy/e8uIvbb0F2KPyz/anLa+lnFOfpc19syNbTz/qeWMW/Ocn1pwvpT367quzrk4uTdZ7Ol8UdlCuvNEvnOY2LdirYvCEte7VstkYUqbd7xoo2mjdIi+JQsX68LfDZSqh4hd3N/lw1qIvLV1jRL7ifV+49gnPMeF6J17ITVDmD8V5mL9MYdx4f/lgXq+K5Yyditdvu71ixuDUPUQsRfHJW+XW9yhhOKLObNVvFg/7eVrtA+rYc63v4tXa+IBcMJtXog9uY9J70yFM4JY5BixH9ty1sT8kD7hehfq2RaP7lNDEbWQs+alswptTzYkofXpbVERibT4HnQt5DyErYbnzffq7TJx7HkTnvMe/3s8Hot12T7Qle4YJPbF+uxQJq/3m4QpbN5RvY0bmZE6RNmSiwjjCcbOsTFEZUSnbeWw1rHDjxV733rXZy1mmS726c5xR9jGpZd0PakZwvytMB9HpOmZSz5Qz3jFEscuXb5uJ3d5Yxg29mQVh4uTG9yhPOTNu1jFk16+RnEs1q/OVsOcbX+PyjjmlQ+Ak23zSRnHnal0kyp1iFzQGLEnu3ay8ReH9InXu3p8j1of36WmnNkWCU1JN46+mEPBYqPTdGe++LbCjAtNqUcZndK9D5OE89xEsedFPmfcj+1yZ+XVDh17EY+03m8S5lZnunmLiYrxO6TvblyaZ4bYy2DL9S51wQyx96z3m8c+2TkuO4LpqRnCHCDMpKry4rzaLTPGLly+OiNuDMPHfvw+uhC5wR2KvHmXq3jKy9fy0tU59fJVmn/g2LMi8zDXfCzzTNu8GHvlHFccFQeOXbrnUmOfeL2rx/cQdC3nVoTVzLrVGPkPOfUGbLO05ng2ZbHO++0wXjvGzRV7tr2Gao6pac2VS714nkFiz5ujnMJ7Fp0lzGLzVg8CjUp+u0P67sb7Gz1O7PL+rh7WOnb4cWLfGtRc77VZi1kmjH2uc1zlCNZzLUSYPxVmXEeYt9K+2a5Y9jqy2OPLV7tMetbeIjlW6a3uUCoTqxmorjJ/OfbsdroyPuAx2/6uXK3tFScFzLXNi7FXD2tFh0glDhG7GOZNjnUJfX0/60rSc2XWLW1ReaA4E7MSXkfMnUVb6+xinDPPHyrHuKlirySVxYk9f2EYJfayOcop/CZhxnUeNUv5+PE7pDsDVcwzduz6/p6vd2GBwWMPDXopA3Wr2O9yjjP5XwIJM8zzo2Hu7QlP44Sf5aJnu2IpYi8vX428McwRu7cmWe93uEMRN+9yFU95+Vo2pZ5om2l/1w/pxUHgqHPCbb6dhck7ZKrYj5C6Lt3Hjr0ocmtYnvUybnWuWWHUUfl1rhDzkg7cSl6Yvtj9od+05/ODTVcP5HM+V9m2ltbVmfoxbqbYo836WMXRq5/yc1/PXxhGib1sTn293yTMbPOOSpPv0yPjdEjHVV0RRu09UKPELu7voQbhsNa1w48ReyUgOcobxz7TOS6KMN/mpzqd3STMKJz0aCYfqOePvbh8TcPON4ZxYw+xHpNvcocibt7FKp708jVpnHH18QFT7e/a1Zp0ANxmmmabV+5M5QyU1iGDxp7u2nv5+iF96PVet+zptOKDGtHJrquAJJg8PSeFkCwczRcvXc792jEu2YDbh/KpYg9lxqs4qr1IZXTVM0bs+ao9eQqfNMx0816s7/0W3kAdom7Je3Vx/OKeMGrs4v5+/EZreqO6MWLfJzbX+51jj6bNco4LNZXfBZNiJ8xfDjOpOPqlcqCe6opFjj2/fE3b1PoW3iixy1NvcocitzNbxTNfvkaF1sOcan8Xr9a0A+Bjsm1eiF3OQFU6ZNTYj5rybTvbGKImDLref0eel7sTYv92Kz7uJmH2u3OHEPu3W/EdxP79Rnz4sugnwvy8m4QpIvbv1d+bYPiEb8eu47D2ScT+7VZ8x+/Gzv4OAADw48Jj5VxXAQP7ZgLq53BYA+6D/R0AAGAg+xByLtyAMT2f+CD/FOGwBtwH+zsAAAAAAAAAAAAAAAAAAPh18XjH4ysAjH5M6G9lmP9J5f7YZ393RfubOwAAAJPgmShgGsKXAsUvEraWDjMnXw/sKcO4b90nih8S7v4MvBD74xF/KLEjrH+JfaAwpY8NXJ9VGahDTmr31Z1jFw3bIRdkoIaN/WST6rNOEvsJxD597DcJU0TsxF6fWF+a2Dc/GXvnB8m+3yEAGqK7NmEIQesi3rhjjjDioP/GaLHemf3IFZf1P8TYKx2SLy3E/lisPxYyVl/8/2IfKUxx2MrVGaiROuSsVl/dOfbWQqN1yNsZqIFjP9MkZdbJYj+B2LP/zhf7TcIUEXv2X2LPfy8uTeyPxwCx9w1t/2qHAFMSxybtE50L+9Ri/ZGjNa6Sr03SydkdzdkbnH3+U8v15pSP+aKyxYndeW4x9lqHVIiLt7wRe9yyxo33KGHqQ+eKAOdf74v13vt9t87WvLCscBDQqr5F7PKccnuG7ZCjZYv1Rzcpe4dY9dixW1cLs9r4KWOf6AAYSi+3ZPFYN9MBMC7e7rPvNc2zawtN2M70UpjpRUCtLUPEns6X3u6Wl+5zrfe99L5de77YheE18iH9zfu4H4xdjuhchxyqKaQvdwgwmyMXa9JbrTAx21efGenafprthekuJuyiyQEkIx1PpHvFbPH90NW7b4sZ8HhiHHEjcV/GXumQntjTi8Zk7mtj789AjRWmuHb1AKdd71tg+x9d8h7Iukk7CNw8dnFjKuoat0O2du7TteVmjX091rsUfvWKfcbYpzoARvGnoYn7+1wHwHjhjhPfuGHmt3RFVNn5Pfyudi84SOxZk9NbY/XSfY71fvJeZq7YkzAW6+qnszfu434wdjGicx3SdVn3Cx0CzEU8G2u34I+QCIr/Sp5yZlsk7D/Fwa8jAxUKFnfA9DYgX3xrvXGhKR39IM4oH87yJrZjr3RIT+zGRT+kd4bXxh6vm33iDGGKZ5fKcrOu9339bjt6vivKl6xxh9w5dnHOCTtksd47p6Sf4g6ZM3bx3rRo0l1in+wA2BOmePCfYJsX4i9MEWa0gccbuhDm9v/tt8cOMW7saphH/dKyU6z30/cys8Veza5le0G6MYwduxTRSx0inO9/qUOA+SxC0kGeuEvTP60yH/munt/6NRj5r4/lVYWwZHvnTQ408bErm9jfaDH2aofUIggfbzu5+IuxV9d7vvAgYW6tLcsqApx/vWs3n8ev05PwTBvDZbFXb+HKxR+jdchi/bp6n1/8iIfKSrFJOweKvbHNK+ejtNiknUPHPtkB8NERZt9VkFrm44djF9q6TZpn1w7tXKzzz3/jA1sZ5l5lvepRYq+uzezSfc71Hgqs7sWzxf6IQ4qCvPw+7jdjD3UIWba+Dum4rPuRDgEmcvLvBov1q7Ph13KqON2Nsl3sZAZK2Scv2VHFMJsT46V7Y691SM22XPoavo/GXhygxw4zNKWZgbrDej+bhSk65M6xi3NO2CHR9DTOG2wM4tlQatJdYp/sAPjoCLN6JTB27GJDJgzTuNVZ6+xinDPHdq4c0p8zJNvCuLF3X7pPuN7vvmtHBbZOZ2/cx/1o7PnmnVXdPL+XF4CDdwjwkxZ5rOMjOWElE4/TWJjcShhHRQk3cOLf4I7ikl1ysfvrKtJrhvxo0bXbZnNGURxhihPTMOrfKxBjVzukJ/bkuHRMvD72tMG1Pw2NEmYRrDrxDuv9VBZGOwjcPfbWsW/0Djl6JjrMKnvHhLGvx3oPTRebdIvYJzsA7j/3XfDMdQA8JqkZqFnCfN4/breMa3HJmodp3Opc885vjNi1MMtL90nXe9euPV/s+5uOkuCUQ/qb93E/F7sY0akO6eiKn+4QYBjy3ruua/P7ESb/o3ht7wiFJntgnlM+psstiueLly7nfu3IFcoUP5ORfgFHiqg/dm3xvtiT6OPZr4491N76+s8wYe4ThaX3yqJrkbnXu5qFSffMJO8wy8ZwQezKnJN1SHyLetzAaXvHhLGX34NTmnSL2Kc6AGY1NS545joAHpPySKbatcOEcEPauK57JIe58WOXwpQv3edb7/279nyxRxVFCQ3hkP72fdzPxS5H1N0hYbGeyn+yQ4BpmY8PC8yz0Xdyk9hvEma/O3fInWMX3blDfit24fb8g4j9v2o7Q7zgufQq6Hdjv9RNwhQR+7dbIbnbvQyH9AwdAgwhjGFkLwIAzO9/r1B/y51jVy54uAoCRnffvfjeh3QBHQIMYh8wyB4LAJjena9Q7xz746Fc8HAVBIzurnvx3Q/pBToEAAAAAAAAAAAAAAAAAADgFckHD44PEzAyEwAAAAAA4BrJN2ezD9AalyRikq9GbtNf+5BE70cuv1dm5f2El1bEM8gAAAAAAOAGjFtD1sk476PsinFr8nOYGk15KQP1ic9PXFymXty1FZGBAgAAAAAAN2Dc6p3zzjwexnlrj4zSMzlSpJjez0DFy6T5nP03z7SY9A0ab62TfrUvuVjvvV/XdXXOJXOJZYZhXXkQap4pC1hqUig0LqGceDRIbgIAAAAAAMAsjFu9NdY7Y1yScNoeNiueOXs3A5WN+snSUVlhae2L9fLrmY4yo1Z7u4iJpCIi6bE6JQNVDFkqm3SUFpUhThQLBAAAAAAAmM8zI7JY7717pmyemZKQM8nzM+0MVPq+qGx8T5HaOUqQykpm197AlKZ6vF1CWWKCJ29CfwaqnFpNZ5WdWURJBgoAAAAAANzAllTZcyTR02zZYKhogTfGQAnzR4/eRQ8A5q883yZL6Zq4TD0DpZRZBhh3S7Px0qCo+Dm78FxeObEWEgAAAAAAwEyyVMuRuUnGMAnvapJ+etLHQMn5lmcZxfN/ZfPExdOJWgZKLfPRnYHqqL2siDFQAAAAAAAASgaqeEH48dMbY6C013sbtzqXjoA6HsxrZKCU9ypVMlBpmQ85A1VOkxtfNun0e6B4BTkAAAAAAJidmIHKsy3hZVHFsKj8g261T7rp2Srj0gVDqc41xkDlZepP4Ull1j5Ht/+u8pIquUm938IrYiURBQAAAAAA8J5PPG/2b8+w8bAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8GXHF/uue3f4u2XWXmS+WP/Tn8H7cn+O3HWyoSP6buP/rfah19E9/OJxHgAAAECDcWssubUyLroWz2bcLtONSxbJftR84iYuK9O46+8iKmXWI/r0p/Qm7s8Juq787bgRfbfx/1b70Ovod0x8XAIAAADwiuRqe7E++sm41fvigju9PH8pA/Ufdw3/e2fSqO3DN7Qz9+cEXZcZOqLvNv7fah96Hf2MmY9LAAAAAF6RXVNHKaTnXViRU3o/A1XUURR8PA2RNG6x3lvrhN+UFZf3CqHQZPpRVVj+GO2VlaDefyS1C42PGx6VEOZMFj5C7LzZmbo/B++62TaGf2v8D3TdqOsoWt65o8x8N1ys997vcymBHhOVJn01zMc3j/O/0ckAAADAWNQxUNvzBsVjB+9moJLhBeKdSVLlYl3SPPHKLa7xVAAAHsNJREFUXBiykN9FHIXGv0n+b/OS89iVO5M8orLxi/WrULtQSTRnXnv0q1rtE/bnsF0338bwn43/bteNu47SfbOcPz2y78d8k6RRsrOA3qS7Hpf+uZMBAACASWjvgQpXw/XL8/LtUM5Ef8gtis0WV+9MxL8AF9kwsUxxWrxoSJNp5WmFyHcmRUTq7UhauxhUNmceQtncO/TnsF0338bwn43/btdNs47Kkp4T96q3+EJLivi8XfQmcVz6l04GAAAAJqH/vXe/Qs6u398bA5XNIN6ZbHUqT2eUbRUrLe9MxFsgLfageWdS1l42Xgtzn7u4F9Grq9c+X3+O3nWTbQz/1nixnV/vun+r6APrKN8Na8kR6e8HcpO+F2ZZmlbRPx6X/rWTAQAAgPHId035BXKac2pkoPQxUMWtQPP+LZko3knotyuv/W288sdtoYVK7dn8p4ZUnLihvUF/TtB12eJDR/RvjRfb+Z9dN806EruunhypR/EjYYqlfeu49IVOBgAAAEbU88RB8tMbY6CEuo5JJrxNI3oDhn63V29/eddx/Bwvkfzf5ncRxhV/m8/CK2sXG78cD6oUS3Tf0EaF6LFP2J8Dd918G8O/Nf67XTf0Okr3zTI5sk3UkiPF8f75W6VJdz0u/XMnAwAAAJNo/0X6oV/Mn8tAib9c9gFT8ReFwsQ1v7sQ7my0Co1LSwiFJmUcVYVy9gWTJoll1iNKqhY+rWWyd2hltyjNG9pb9OfgXTfbxvCNxn+h64ZeR9Hy4mfatol6ckTre6lJdz0uPf63kwEAAACc03zu4EfKvHPt80X0bxXN13VDr44frP0r66g+KPUTht4UX6v9/zsZAAAAAADg68LjXLxN6HPoZAAAAAAAcHP741ykRj6ITgYAAAAAAAAAAAAAAAAAAAAAAPgY3hoCAAAAAABuJ/vCuDNSjsS4NXyc/OSbLxbrr/tQUO2rRGlF3/160tGIMvbXMlDRZ7qLpY3jVSQAAAAAAOCnJQmRxfrVW1MkToxbnYnnNG7tyytdO+KnklfKKvqFDJQc+ys9Yly6juKuN8479/1gAQAAAAAAdFlCJMk17XmmZzonnbMvkWJcki1ZrI/GUj2XD6N7sgRSNjEbq5Xnv6KKlDmPyUm7pSZFI46OCcdcx/JKmVLse5HOHR0nLd7u5SS5ZtzqzC+k2wAAAAAAAHTCGKhly2gY5/32n9WZLBvS83RdkRlZrC8TQFsxUfHiRLFAdXolKVM8rpfnj4SWLNbvqSwx8HJi2oAkIjGpFCfQ4rSb9BRfmLhYf2QIxWABAAAAAAB+gPAeqGNkjbPWP3NPRQYqzLNmjpRJOYCnSNRkqZcyx1MMJJJSLcJIoVpSpki6qU0K5WgpIrUJerquufjx/zj40NPCu67IQAEAAAAAgN8mJkS2h868XRbrrNmHRJ0bAyUM4JEGRZWZF3GivLxWkTwqSnqTujxOK8+pKU1SypSfPuxefJtD6eEwiOqogwwUAAAAAAD4bdrrsr1z/vlhPOec8Im850/6GCgxKyKme94cAyWnX/Kp6iikalJMnBhnyvrLLOfUB0Yt1kvvg9+FIWkZb6W5AQAAAAAAvk7OQB3vPTrek3TqW3hqsepzeZ3vgRJeQS6N/8nnjH5O38QkJJySIo3L37QkpZCSMuWHAov3QKlNCoOjjvxUNvis/6VXAAAAAAAAP0DPQB0vI3qmQuJBN62Eh/Rg3EMdw1SWKU7cWxMPtVIqkufcfnbV8UpJ9dHrx6UEk1im3KTqt/DSJj3iDGDRICH1RwYKAAAAAADcz79lRH4w9XJNk3q+NAgAAAAAAAC8jAQUAAAAAAAAPuf5aB75JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbsA4/Z1Dxq3rGr7sZlzyfqJoweeri9Z45k+0My481L5Yv3bULi1+NDspIS6xFVM8L69uAgAAAAAAkFUyUMat3vsszxQnpJzZJocSFms/lIeRM1Dp1MX6WixSAkv4Xf+H6OI5+XwdAAAAAACARs9ALdZ7uxy/N271zvnoxy0H1J94OYYMbSmfxXpvresYQCWmkLKJFR/JQCWlPLurZzEAAAAAAICbUTNIWyLmyMc8EzUhXXM2B5RkevZSF+vX6HG6SuJHTCEt1nc++ccYKAAAAAAAgK/RMlAhoxL+syVq9rE+RQZqe62SM/mLlJ7vSEpTNFsp8cR6MktNIUVvc3pl8fJ3WfMbaSXTM4ALAAAAAADg1pQMVJQa2v9bjn4qx0BVnskr81LPtFT8YqkXU0hHBWoBF4yBCgEk72aPx0CRhQIAAAAAAJDIOSPpe3BHosa41VsrvQfKuNoYqDJDc2UGqvlW9aufwssiOvVGLAAAAAAAgBuR8yZpUiZ7A1RIUJXfwqtmYZJCjdveA9WZgcqX3p8ITB7si+aI3jClLi7+dCoDlZZJBgoAAAAAAEASvUbpGK+UJ4P2QU9pviV+g1PHq5geydCq8Prx3gxUOjArznmJr2zKM1DK4kLFZ94pHtfOM3gAAAAAAAAAAAAAAAAAAAAAAAAAgI8rHwssHpsDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYxGJ9eN+St8vj8TAuefHS88ds4rHsMdW41dtFnrNV+bNmAAAAAAAAzGfLGm0W68tkUyUDlSy+p6POZKDCkmSgAAAAAAAAJpUmoI6JvRmoqIAwHooMFAAAAAAAAA6L9eUTcGcyUMf0kIsiAwUAAAAAAICUceV7oDKVDNQ+9OnIIklzxi+bOsqMfksGCgAAAAAA4A4W66VXidfHQG3po+id5IyBAgAAAAAAgEpMNjUyUM/fRL9mDBQAAAAAAAAOz4/fHT+8MAbq+QYof5TDGCgAAAAAAAAk4rc+hXeKixkobRBT9jrzypz12qszAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAezBudUb60bh1E0/Y591/OOZa13VdvV16Kl2sT2p9y2J9Z7UAAAAAAAD4BjkDFaeIjHsmlp7JpudU47z3WwbqfPrnpYVUZKAAAAAAAAB+m5iBSscobSke41bvnHfm8TDOW+tezUBlVS7We2tdMopqsb4cVFVOzEZgXTeuCgAAAAAAANcRM1BZXimaaKx3xjhvF3HODsWQpcX67PG9IwEWFS9OFAsEAAAAAADAT8mHEa31DNSyWO+9ew6JKt8D5cwjGqskDU4qU1bFS6GyRwCf/xUn7rOTgQIAAAAAAPhhJ8dALSEV9NoYqKy6x0MeFBU/ZxeeyysnyssDAAAAAADgp5x7D5SWlkroY6DEZJH4WB5joAAAAAAAAKahfwtvT+tE38Lry0DV6hJmLjNIp98DxSvIAQAAAAAAfpicgXrEL4g6JogZqO6v0QlP4D0e8himzm/hHQXzLTwAAAAAAADwsBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATMO41Rn9d+saPmBn3LpG80YLGrdunjMbt8afvUuqSMvUFo997gt6WjsX6/+hdgAAAAAAgLuoZKCMW733WZ4pTkg5s00OJSzWmmoGKiuzZ/HPkduZTl2sVzN0AAAAAAAA6KFnoBbrvV2O3xu3eud89OOWrymW1zNQeZk9izccA5a2hRbrvbWuYwiT2M5/y38BAAAAAADchZqBWqxfndn/eez5mpCgqeRr1AyUUmZ98Vbz93n3Uhfr1+hxusoIJrGdi/Va4ioqGQAAAAAAAN20DFRI3oT/bPma5zAmIQO1vb6pTEsl71cSyywWj4UlMkkqayt+a2A8xKqSzFIzZVEL4hnIQAEAAAAAALxCyUBFaZz9v+XoJy3ZpGR2amVWFq8o81LPtFT8sqpXMlBJBTyTBwAAAAAA8B45A5WndrxdonyNcau3VnoPVC0DJZXZs7jYoDLZFM96WQaq/q1AAAAAAAAA9JAzLGluJnsDVMgHld/Ckz4nt/8glSku/uJ7oB4P47ZMV2cGSmxn8vG7dAwUT+EBAAAAAAC8InvpkvgipzDoKUnXHMkY4bVJ8Zgl+aXjyZCqfFxU3qCKqKbwtqneDJTUzqxP4srJQAEAAAAAAAAAAAAAAAAAAAAAAAAAJlQ+ath+ug8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODDjFPeh3S8Oyn+/THV22X/+ZghKc24MFs+5/5D9oKmMPNnLNZ/uAYAAAAAAACU5AzUYn2cLdryNsZF2abFWrNnpOI0U5jBuNV7nyadtp+M235zlP0fyEABAAAAAAB8g5iBihNQR+JGmtW41TsX5o5meS51TNjmdObxMM5b685noBbrvbUuGTC1WF+Onyon5l/D4zt4AAAAAAAA/0bMQGWJIaNni54Tw6+O0rYk1pHLMm711ljvjHEhNXU6A5U9qZcVv+gTt18wBgoAAAAAAODfvZSB2kYUHROLYVIhCxT+85xzsd57Z5ejzGJkUhjAVIxYSodmPYqHBbOqi+jIQAEAAAAAAHzDy2OgsonhxzTvdPz3yFXtP772FN6iTAhFiRPl5QEAAAAAAPAPXn4PVJ5CMm7d3+5UDGPyz0FPfU/2VcdAFRkoxkABAAAAAAD8Ov1beNEjd9K38IoU0pY5isY7HXPG74pSFu9QZpBOvweKV5ADAAAAAAD8u/wjcSHHdPwiTtpEs+/joo4cj3HJy6Hihby1SgbqxCfqpDFMnd/Cy5tPIgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgF+2WL/uvF20icatzhxLZT/WSg2FGrdP2hY17vh/KFOfuK5FkUVF2Yz75DieePG+JjUYJ/dcY8kwZxSNtvgxuVZoGXwyd9LO/ibJtUsruFFoRy8V60OeU2lnb0Rnev50mdLizZ5Pt8993jfD7N1sWp3c7BAAAAAAAJqMy9I5zsgTz2SgFuuTLI8zz2n7Env5z3xDnKEKyaZyonQXLlUkxSU3urtJVcZ55/yRM4hTJ83MweOxWH/MpSweBaN0RKvgvJ1nlpRqNy5pdKWTpDmVMJMeM9Yujf7MI+yOSJj4mRW3hdLu+VooL4fZu9mIjT/fIQAAAAAA6LRETTN7U0vNSL9L0xTbrbJxq3cu/OJINokTy3vgSiM6YuhvUoVxqzNKjqBrAJWeXwiLJ+X05iOyDqi1s96kdu3vZYLkMCX5DFdmoKoV9ZcpLN7V85/IQL202cixd3UIAAAAAAC6xfryGR9xYn8GSrzZlRIi28RoYE1jYk9Fcn1So/ubpNoGisgN6RuupAYRFi9HtnSlR7Jkm97OepPatRvX+5iWNGcapi2ewhPmFNvZH1Fz8atW3DZXT88nT+Flob8Y5iubzZmUNAAAAAAAJ0VvD5JekHTkYjJnhx9p6Z5wr1yfWFZduzF+LwOV1p69pCc0INzjK0N7um759fFT0Tgsb5fF+ueUnnSAOLzrtQyUWnvolWaUlTnTMNO3P+WPsl2Vmmksft2KO9/zYgNeDPOFzUaOvT/DCAAAAABAF/F9L/vE/jFQpzNQ0Y/Nic2KGo3ozECltatVbL8rcgQn3pwj5RfSxc8PZkkjq7Szo0l9Y6C6n/CK5+wPU+7PD2SgLl1x53u+WO7csu+Ngaru/gAAAAAAXKnyEphPvQfqeXdr3OqtzZJN4sRmc8OvWhmo7ibJY6DKQWHR4KD+m/aO7NXJF/pkT+Cp7exsUkft/a8JSnIyRZhyxkTtz6szUFevuPM9fyz4fgbq3GZD+gkAAAAA8FHRF6+OG05x4okMVHbnenwLb5+2p3miNNGW5UmTTeLEVkWPpIpE1ujuJrVEt/f6TXt4HkpdVl08alQal1RmloDS6+psklR7kiyq5inkOdUwi6fwaoVfmoH6yIpTG5CVmfRSx1N4L684tXWknwAAAAAAnxaP1Ag3teXEMxmoR/Jq5XAba/LXTCf3xft7gLSJ+RikSkV50dmbnvPym01qOe789XYKWYN05u1lPfLiR/vzr8HlDazlGtoZqLJJSu1Jh/ZuCdG2JIcZ/aI+p9xOiTjniZ5/c8X19ry4F6phvrHiml20zduKCAAAAAAAAAAAAAAAAAAAAAAAAECH8k3LPK4DAAAAAAAAAAAAAAAAAAAAAAAAAMBPEb5W/zW1tizWv/KI4vE9s3+K8sV2AgAAAAAAKIwTkg3Z+51C4uPIhbQmRkVsxWdlPqeKFRm3Zh+kb6RDTmagPpFgCWVemA3L2mncf2WgLrVvHqS0AAAAAAC4MS0DJSQ70qmL9c4oE+PcyT5DMuNi/ertIlf0TEuF6VdnoD6RyTnKvC4DlbdzyAzUviX80jA1AAAAAADw7/ozUP0T08E7W/Ihm/NZr1qmcz4aPHVlBioqLl4uakk0qCsudrHeW+uE3xRlbnOlqbn8Q4FJeWIvpGELfSU8nyc2Xpj4WjuTBvQ8HahmoJROBgAAAAAAU+rPQC3Wl9kCcWI72dQaA+XtEn51aQYqmVXMQCXps8W6NI0j1ZOXGT1iWGZdkszOPmf5XKAQUlFcljTLB5+FxqsTT7cznlOoXRQ/hff8vzN6JwMAAAAAgCn1vAcqeSdTOXKlmKhloMoytYneLiEJY9zqTPyyqaJV/Rmo4plBOQMllqblWYoy4wcQkwXKzE7+qKJcpjhNHGgmNl6d+FI7pZxZewU8118yUouhTwAAAAAA3MeJ90DFqqmOcw/c6RPDgleNgcqKUp7CUx4vU2rpLHMvV07biD1WVpRnoKSUnNj4cuKb7dRqLx25py3duM3471/4AwAAAAAA3/NiBkpfMH/GSnkPVKWiY6Jxq7f2qjFQ0ruI1CxMOVGsRXy/UffYIrl2PdXVkRBT588mvj8G6mTi6BjZ1n6/FQAAAAAAmMyp90ClaYktoVBOTEZIid/Cq1ZUvhT8kjFQQl1JriukZsJbidqPmpVlnnq/kpiB0jIyRe4mmdG454uWhMYrE0+0s/EeqL32qiQDpXYyAAAAAACYUvYmpme6J58YDYEphyCJE6OpxyftxGRTWVGW27goAyWm2o5PvznxW3ja83V6mfKX46Q4lQxU5aHDvZToHd5FS8XGy/OdaWf9W3h9KSQTl3F2YQAAAAAAgO/qyECdf2rskmp/osw3K/q3JgEAAAAAAPwwciTnkYECAAAAAADAZ5GBAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgBxi3rtF7foxbV+fcGqTvADJOnl4UGXFmmxgvYtzqzHPO5+/DxGzpva7F+mzKI118/yFbvrOdx2xqRXlETYv1vbN2+0SZ7YqOPvmXugEAAAAAwHyiXMOWJoqzRcat0W/jpITVkhFJsmmxvijzkWSgkrqSdFSZPUrm2BbfM1ze+63MzjdnK2HKFZURnSn+Kp8os1lR9P9/qx8AAAAAAExnS7+Er56leYb9pzQpUy9OTDbJE52LE2BnM1DeOe/M42Gct1aqqLudxU9aBqqzJ7KZFuu9te4YWhV/Yy6Un8xVDV9cPBnBFS9+TI6mFk2SG58EwpfxAAAAAADAy7bHzNKhUJttjNSLmZ3WGChvl/CrVzJQ1ljvjHHPct7IQKXPt707BqrI1CzWF0khMQO1r4XyebukTHXxaJSaK0cuxXMUTWpWVHQMAAAAAADACfkrlaqDmNJ8lVxWPhKnVuae5HgpA7Us1nvvnkmu8j1QlXRJbWST9LhfGlH6vqisrrLxRUKpmULKyygSZvLiRaelNUfLae+UksaGhdSYcau35TIAAAAAAAAtxq3e2pB46BkDVRkLI75fqZ7VCj++kIEKmZT/GQOVvzFKKTmfRRoUpTyFVz5bJ5SpzVk+b1emyrZylCfqKhXJoQEAAAAAALSF3Ev0xqfme6A6M1Di280fZbZoz4G9koHSymx59T1Q0aig/szOmxmovsXF6NRXN/W1k/dAAQAAAACA98VPbm3/V4b8JKN/ujNQ+2LJ1DIttSV0vpWBykc2tSqqDASSGyBmdo70WyMDJZQpL76/+kl/ns846WXmtcanz1+SgAIAAAAAAGdFr74OP3sfje5JEw7RC5H0TESepthzXPGooWeVeVaqkoFKhxyFZ/fEDFTni6DiOdMXjTcqqr6MXEnNCemeUJNzjTFQYpnC4knrs0fpyslCk/TGN3sTAAAAAAAA/+MTT6n925NvPGIHAAAAAAAAAAAAAACAu8kfePvVB7VGaScAAAAAAAAAAAAAAAAAAAAAAAAAALOovbd7sf6Vp/yOb8790xvBX2wnAAAAAADAGcYJGYjsvUkhG3IkSFoTk8neLkpFaWXH78sytSbVfSLBEsq88MtxWTuN+68M1KX2tfZij7+5OAAAAAAA+F1aBkrIgKRTF+udUSY+FuujycY5o2Sg4tRLKEoq86WkzCcyOUeZ12Wg8nYOmYHaV+WL3fLm4gAAAAAA4Jf1Z6D6J4qFihWlY3+25MOJiuqiKuO8RlRUPlArboh10nirvMxtLmnwVxbYXp4YW9o1QrDC83li44WJr7UzaUDP04FqCknp5GsXBwAAAAAAv6w/A7VYX+YAtIkdaRahouc8YpnnM1BJK8QMVJL/WqxL0zhSdXmZe/qmaF2RWtvnLJ8LFHqrKC5Lmm2ZmrLx6sTT7YznFGoXxY/RPf+/rU2xk69eHAAAAAAA/K6e90AdM0S/iB+yyyZqg5g6M1BamUWT4rdFSU1NB/zIGSgxraXlWYoy4ycIkwXKzE7xrKHcBdI0caSY2Hh14kvtlHJm7YfknmslGal1Jnf45uIAAAAAAOAXnXgPVKya/7ggA9VXZkVWlPIUnvJ4mZJm6SxzL1dO27RDFjNQUqJNbHw58c12arWXjuTRli/cZuz8wt+biwMAAAAAgN/1YgZKX3B7Pfkb74ESF5SapI+Bkl4mpGZhyoliQ8QXFHWPLZJr11NdHQkxdf5s4vtjoE5mfraay5FkfWnENxcHAAAAAAC/59R7oNJcxZYmKCee/BbePuNeq1jmqeyDMPMxybg1tDK8VqidCivLPPV+JTEDpQVVJF+SGY17vilJaLwy8UQ7G++B2muvSlJIaid/anEAAAAAAPB7svcrPYcR5ROjcTHlo1jixPITZmJF6fLi+6aOjIjYJCUmebjVc0knfgtPe75OL1P+cpzUUCUDJSflklKil3AXLRUbL893pp31b+H15YBMXMbZhd9eHAAAAAAA4NPOPzU2T5lvVvRvTQIAAAAAAMBUyEABAAAAAADgs8hAAQAAAAAAAAAAAAAAAAAAAAAAAMCEFuv5+BkAAAAAAABipIwAAAAAAADwUcatvMYaAAAAAAAAn2NcMgBqsX592tJSi/XeWpdMy9NWexlh4XRIVVLEtlyYNRQjVwQAAAAAAIDBLdbHyZ4osbQ/m7dYv2eU4sf14sRVmsQqH+pbrM9ySsc8R41KRQAAAAAAAPghx/iloJHHSYcypYmfLTmVpZ3iUVDbZGEUVZmBSqaIqSytIgAAAAAAAAxMfQIvSmDFo6SSxNC+cFaInIFK80limWpFAAAAAAAA+Bknx0BVE0PiROntT3kCqjMDJY6BIgMFAAAAAAAwsOgtSxspy5MNctreA6UlhoxbncsTUD0ZKO09UGSgAAAAAAAABlZkoIqxS9F88fipWmLIuGSYlXHyACxpbJXyLTwyUAAAAAAAALMQH7gDAAAAAAAAAAAAAAAAgH+SPe/Wfu04AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArmNc9gYo44R3QZnonVHh+3fGFW+QMm7NPo9n3OqtlRZvWqy/7rVUtQ/3pRXxiT8AAAAAAIALxamXPXmkZaCSxJMz2cTHYv3qrSmSRsatzoiLt5TZrHdU8kpZRWSgAAAAAAAAriOO/WlmoMJPWeYmyTXteaZnoeLiDVk7FuujsVTP5Rfry3FV5cRsrFYeXlSRMucxOWm31KSj+mjCMdexvFImAAAAAADAZKQUUk8GastcCWOglpDG8j7KZ4mLVxUDkRbrywTQVkxUvDhRLFCdXhkDVaTs8vyR0JLF+j2VJQZ+6bOGAAAAAAAAv+bVDNQxZzlgyLjVmcV6Z60PpUmLH4OFhMFJ5TCpIlGTPUFY5njSQJS8kjAeq/YUXpF0U5sUypGedGw1AQAAAAAAYBpXjoGKfuetdd4ui3XWhCf7To2BEtogDYqKn7MLz+WVE+XltYrkUVHSm9TlcVp5Tk1pklImAAAAAADAZK59D1T4pXfOPz+M55wTPpH3/EkfAyUmi8R0z5tjoOSsVD5VHcRUTYqJE+NMWX1gFAAAAAAAwCy2lzc9Ho+3v4WXlPn8/fGepFPfwlOLVZ/L63wPlPAKcin1k88Z/WxcdQxUVqRxx7vYs1+rZQIAAAAAAEzoeJlT8eG36BfxROUxt12U1YpzVd1PnIkZMHUMU1mmODEJ7AhUyYQJc24/u+oYqKT66PXjUo8pZQIAAAAAAODTaq8BH7MiAAAAAAAAAAAAAAAAAAAAAAAAAMAw/gDNdyryY4e1YAAAAABJRU5ErkJggg==" alt="" />
0x3: 环境变量函数
1. 环境变量的一般形式
. 变量名=变量值
. 进程对环境变量的操作包括
) 根据变量名获取变量值
) 根据变量名设置变量值
) 增加新的环境变量
) 删除已有的环境变量
) 清除所有的环境变量
. 所有对环境变量的操作所影响的都仅仅是调用进程自己的环境变量(进程独立),对其他进程包括其父进程,没有任何影响
2. 获取环境变量
. 调用任何操作环境变量的函数都需要包含标准库头文件: #include <stdlib.h>
. 根据环境变量的名称获取该变量的值: char* getenv(const char* name);
printf("PATH=%s\n", getenv("PATH"));
3. 设置环境变量
. 增加新的环境变量或修改已有环境变量的值: int putenv(char* string);
putenv("MYNAME=littlehann");
若变量名不存在就增加该环境变量,否则就修改该环境变量的值
putenv的指针型参数被直接放到环境变量表中(地址传参) . 增加新的环境变量或修改已有环境变量的值: int setenv(const char* name, const char* value, int overwrite);
setenv("MYNAME", "littlehann", );
setenv("MYNAME", "littlehann", );
setenv根据参数3决定是否进行覆盖(当指定名称环境变量已存在时)
setenv的指针型参数将目标字符串复制到环境变量表中(值传参)
4. 删除环境变量
. 根据环境变量的名称删除环境变量: int unsetenv(const char* name);
unsetenv("MYNAME");
5. 清空环境变量表
. 清除所有的环境变量: int clearenv(void);
clearenv(); . 该函数在清除掉所有环境变量后,把用于表示环境变量表首地址的全局变量environ设置成空指针
6. 实例代码
#include <stdio.h>
#include <stdlib.h> int main(){
printf("PATH=%s\n", getenv("PATH"));
putenv("MYNAME=littlehann");
printf("MYNAME=%s\n", getenv("MYNAME"));
putenv("MYNAME=alibaab");
printf("MYNAME=%s\n",getenv("MYNAME"));
setenv("MYNAME", "hello", );
printf("MYNAME=%s\n",getenv("MYNAME"));
unsetenv("MYNAME");
printf("MYNAME=%s\n",getenv("MYNAME")); return ;
}
9. 内存管理与进程映射
0x1: C/C++ 进程内存布局分布(高地址向低地址)
. 栈区: 存放局部变量(包括函数的形参)、const修饰的局部变量、块变量({}内的变量),该区域的内存由操作系统负责分配和回收
. 堆区: 使用malloc/calloc/realloc/free等函数处理的内存区域,该区域的内存需要程序员手动申请和手动释放 {
. BSS段: 存放没有初始化的全局变量、静态局部变量,该区域会在main函数执行之前进行自动清零
. 全局区/数据区: 存放已经初始化的全局变量、static修饰的局部变量
}
//因为间隔距离较近,常常将BSS段和数据段(Data)统称为静态去(全局区) . 代码区: 存储功能代码、函数名所在的区域
. 只读常量区: 存放字符串常量、const修饰的全局变量
aaarticlea/png;base64,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" alt="" />
基于Intel架构的Linux系统中的进程内存布局
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int i1 = ; //全局区
int i2 = ; //全局区
int i3; //BSS段
const int i4 = ; //只读常量区 void fn(int i5){ //栈区
int i6 = ; //栈区
static int i7 = ; //全局区
const int i8 = ; //栈区
int* p1 = (int*)malloc(sizeof(int)); //堆区
int* p2 = (int*)malloc(sizeof(int)); //堆区
char* str = "good"; //只读常量区
char strs[] = "good"; //栈区 printf("只读常量区: &i4 = %p\n", &i4);
printf("只读常量区: str = %p\n", str);
printf("------------\n");
printf("全局区: &i1 = %p\n", &i1);
printf("全局区: &i2 = %p\n", &i2);
printf("全局区: &i7 = %p\n", &i7);
printf("------------\n");
printf("BSS段: &i3 = %p\n", &i3);
printf("------------\n");
printf("堆区: p1 = %p\n", p1);
printf("堆区: p2 = %p\n", p2);
printf("------------\n");
printf("栈区: &i5 = %p\n", &i5);
printf("栈区: &i6 = %p\n", &i6);
printf("栈区: &i8 = %p\n", &i8);
printf("栈区: strs = %p\n", strs); return;
} int main(){
printf("代码区; fn = %p\n", fn);
printf("------------\n");
fn(); return ;
}
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUEAAAEfCAIAAABQ6OPhAAAU6klEQVR4nO2d3bmkIAyGpyfbsRh7oRZLOXXsXow/CSSIyowyvu+zFzscRVBiAAnf6wUAAACPohvGv9DXy+vNOHTZxE9cHSb6YN1qaIpuGA8+xNXglN2JZGFxIlVdzmxDVzUsp0ZHs1qrf/wmV8R8Bx671c7T7IPx5OvACzyD2bxsO8zn8n6a3TDOZyxpr1cf1mvop3ErG5aI0h8gqsEdbNi+qUdutf001Q3rB9W5GodOn1an8L9CN4zjMAT1VlxMMGpHUeL62lTmKh9GH6bk5WzLpr323gfrcNWgy2zYvvqcGoI4Plv36chuGMdxnBMsf3vOgmXFnZu8JqvLWE8zHWGoo9S99PsP+llYt846XT8J62GtFuq97ifb9Q/YZj439+D0XcocabYQ485v170W3TCmpZnulriumbiU3Tw7/el0aLzquW/+Y37YLVkfVHPP132y4b/QL4aaXi5N6YaxuIeYet2MH0463bEFGhURhTEfSZqoC2DeOvt0eScsK5yfpjYBkXvEETtYC+8/uPguDd6RniHk7/ypN1BJBVPvJJ5A+qiTN3I8QJWOdxy3bDhjweaAWGdw2IbNhlZS98kPC9dg3AKzXcuiz81z6bsMuddSri+tDs8+zSUfz8jcGqTNtfj09f+y3SRPsw/ih+zFTIOrE6MJbZ7mg0vvUgjbRypDsNq2Xff6JDdHJsjGbTwV43xxl+bxbdaGHQvO9EX1q/+MDRdWM03M2nBJp2k12cmW9fmWY7T8euqcrKcZebK3d7GeppNnUqR9p09H+H2wpe9qXXF965wwYdkAXcuM/P3oHmkbglnCfN2rYT714344tuHk7avq4htb7onJLO/mh88Oe+zGmhuw5FuSmZ/3qirPc/PWxW/53m3G003UM1Z9mMehJ3vSySBg0zI3j3T9sPfg/LpXwn7F7xoPqwJGfWnV+42OjXrL6zHxzVDPVx9QOJ4zUs1B3XbdszZs1mjJo+BBZrolkSeUk1tZb6Cy7IP70vHytLv2ya1zi7Q0hbXpm09TWESSWNgVTW+yM3mTvnzjuzR4R3qG4PQUorp/Buvai/0ZTyJ9GS4zD6aNR8eIQ9MZi9CbB77UG8EYEaepOnEj00Pz0tYDNmskcth8kn5bjW6y+B02e3TJ69TpOJh52kWybp1TJKPyztMUt2+t5XSDi4wguclx4XODIH2XMkfahuD19gtf3jejvVKXd4A/Pb14qh/+AeoU6dPjQf+y19/Pi+pegT6kr9n7smXD3RCWvvL1raI52m3G53ly3b/KtmnO/ScseCfvl/kzW/GT6w4AAPAw1m571322t3gm/6f3aBmOg0u0amL+8qNXROTxPh3EzAtgTpbyc6ylL7tY9DXUPN3OM534sz6q60thw2CivrqLH8kau2Av7tB/mFcSGJc51QS/MsWnP5duF7cPy9Ja93QzUS1VeYfadWbcpV04AEE3jGHohCNZDDJenagsVfyMIzsnG9YN8UwDjDz7OLV4K4DuHObyOfXBW/VP+vAXer3aJz19O3GjJOZaFICZbgghjKG3OsDj0K3j17iftzrbZBmN8MPza8Bts+UrQoy1ksaK5lNEqwLWQotqqJU9yTq89HQ/MQ61k2iHnawJBZjpw3vpoB6mmYu3wzhK243XFcpxbtSX9lcRv07asL3I3rqCxrveEtLwl1jslIuxrFEtl05P9xLtULulHPHbY7Oa8EjWPm9kc0kb74ehW4zXtADZ01aHVAvdSG04ty7/6CVsPzz90ot7Vys75oedCyVBHdWrCT9HbMPOOlNhw8ni/tBLu13/H62oP2XGR214hx+2x67LxQcdm5MOPPaMh/1OexIvgB+GDdKwENHs+l5M4PgWoCa8+vB2NdGh8fT1fPHDfekPOCh7Xnq5tDXy9qOAcvPSVqidORvNeBi2sUK71kkcMQn7bsZqkcbqV1Svs9zhlrvnr9iw9S1XFdF6NcluS/n34STUzgmRZF4aNvHCMwvXbHfD6EQae+iGTLMEAAAAAAAAAAAAAAAAAAAAAAAAgPtiKk88JBEAAAAAAAAAAAAAAAAAAADg5zAEC3OCI28JofdRy/bLxr6Wr67rLYmJ0Jevxait1Yh4O7SGs4ldtKRp2b4u3Vv5z9g6b9loddmXehx6w9ici0f5fURL8aTE4Um+JbAob53entO5PHvgNojlIC3FlnjPWW8PWtPIZ3sLQTs50zunOX9AS3HnuZHE4Um+JbAo+xTmNtlxp6NuNeFLlNrw+1jXIa6KJRnHktiinWFy8epaivZQYCmN4ZyUxOFJrhFYzCZ+oprwLbZtONZ4WBrBdJhUOuz7VRxBE3tx21r1yWuTrq+l6L0C0vFwInF4kq8JLO7zw7WrCV+j0BUupt51i2KQ565Fros8k32k1/FO5GNqayn6pYpt2JA4dC+brYS89ncEFmVNdVXTxMJqwh2JDPFton3S/FYbXmwk32+ec88e4thw3IhqaynOTXx+GSQCaUqLIpE4PMnXBBZVZmKa0U6sXU34KsJ3mdJdr9mGu75fxK/HEITrMedHN737bhuuoqUomunbYqUZaRu2JQ7tPEv98NcEFsut3bpQ0a2Ee5AMLS07nmxYuF7XDTtqxMbAW37btfVPxe+KWoryA0pcWff7cEUH9SWBxWQOcLLhNPEz1YSv4LXY5Nm+39TSY4yTor0/dH7N1pgM8+bjRttjh35dJbLmUl6jAv+8ep73kH2uje9Hqzbu9FvuZwQWZZ3kO8DvVmDDLeF1m99oK5p8prWrTXZhk2d92WUbcfvaPJh1VQAAAAAAAAAAkPCg2EOA1nhq7KF7N77yZeV+sYe5gES4Nw+NPXT4jg3fL/YwF5AId+eZsYfiwnFwgOWhxmFdYnrexG8Ye+gHJML9eWLsofI06gZYzbcbxqp7W9wx9hA/3DJPjD30V6h5NrzZpluPPfQSoQGeGHv4kjanq2/bcNVmfdPYwzQRGuJhsYdxEfSE7zEbbjv2MPtagfvzvNhDcWLUUd4K+6vD7WIPtwIS4cY8NfZQuM1k7B2nf2Ka9n6xh9mARLgpxB4CAAAAAAAAAAAAAAAAAAAAAAAAAOSwlk4+JREAAAAAAAAAAAAAAAAAAACgRb4h0FFboxBFAoCZaWfjwTeIzMZ0WgUts3/dUY1CcxvH3HG193Qv3Xtv3RzSkh5MNQZ1OdMjo7tpbRLIOwxeL+GDM5uD2wLCxXqIZxTOdp5bt0dRrlGo9gmdtwXNnJ5uzG4JF6ZXRBsJIvymFB9W4IY/oVFovlkSXTW3Quco1yg03385PUH907tQWhU0CkEgDXPe893qvL1yNjyG3t7PXej4HdcofOfpv1c+a8OuiImom3CZQ9SXzmqgqD/aR6qbbvle/PCTSTQaNiTQvL503I5qaxTmdE4P2vBHNAr7EJnZJI3knR6VM3vkcoGlmGgUgsGGDS9iw4mb1ifW1iicW/PchBONsWv88PTLVXQp0CIr8MOanJohPBa3h2xrpikTnf/r2XAVjULRtt8WK1v35/1wuUbhKxFeT4YR+8fDVlnQKASPrB9eetLKD7s2XFGjsA/6m0oc3P/hOa0dGoXCmtaCnpqXVq8F0RFBoxBMcjZsfzDq+j79IFVfo1B9dZ1MOp59W82oxLnuo1yjUFw++33YKadxpDxwQ80QHogj4J20Lt+4o2kdkbSRJQAAAAAAAAAAQAWIPQRomR+LPaw6/X2/2EOAmN+IPRTfwCouQbxf7CFAxM/FHrrnnL72PWIPX7u6BvDj/GTsYe6Mvdwx9lBVbvb38EB+N/ZwcxFx27GHTOSBx6/EHlYNx7th7CFjZFD8WuxhkQE3H3uIHwaT9mMPPxIQf7vYQ8bD4NF87KETj3ia+8UeMi8Nb4g9BAAAAAAAAACAtiH2EKBlfiH2MJ1nr2PfF8Ye7sgTns1vxB4qqnUrLo093J0nPJKfjD2s1ravjT3cnSc8jh+NPaw3Tr429nB/nvAkfjj2cMuEm4k9LM4zfwPhKfxK7GHVMeK1sYf784Tn8Wuxh0X96HZiD3fnCY+m/dhDJ+kcV8Ye7s8THk3zsYfTodXb9JWxhzvyhAdC7CEAAAAAAAAAAAAAAAAAAAAAAAAAQA5zX6eHJAIAAAAAAAAAAAAAAAAAAAA8jS/oDyJxCBBhb62YyLdkEvX6p66Tm00eXhFVvGOjKFK95Vf3kziUd553GCjULq7Lj0RNxJQYWTSH9J7R847mvqzLvlJlj9OvkirN+34Sh7Jq9EQgQjezVUIgbbpue458xGK652x4r8RhNa0DJA6hLUw/3A2jJdNiJL7/IG11dkfLKWncwQckDl9nhGDiK9xN4hA/DDkM0ZXkD8rIM+Nhi8gS60scbrpnp4gNSRzKe0LQFcTEfjhtI7G6UZKY9Jn7flYeOtTg9ksc+oXfzw0lDtVlzccBTybqtG4Px9LEbgiTP5n9Wx9Cf9SC90sc5su5nFboh28ocYhMKeRI5rTGodPSSvOL30s0u3i58Ww9iUPV4Ks5qNtJHOqaVRr3w88QKaYJVeHSxLgvPQ/pzLZWW+JQOdhqLft+EofydHrSUJu3DS+tzJgYw20AAAAAAAAAAAAAAAAAAAAAAAAAQMPcUI4Q3UMAAAAAAAAAAAAAAAAAAACAhH4IQ68XPvRh5y5YXfdzKydKZZ8ALkdtTenLCeUVHcZqOkCfWVG1Q81wwhB50KWy5QjP6h4C7EfY8Nys5HawYotUs619xl/VFQcrVzO0zjEFFm0ZpJP7SwPsRLtWIaqgtoSfmWw42bT8aPuTEmGWHky9dl2uZrjekxDsmpkahdlE8ydqhlCRyQ93wxhCtBe7Mi7hh4UMoN0PLNkOXu+2nuqrVWvW5WqG2qNaNrwYu+WHT+otARxkkkx67/Ue+2ExWRX1pbOyIaU2LPxgomiYt+GPqBlGRTLGvsktkKef0z3M3iyADGI8HNuwmm5WNtwN4zj0p+RwZaNOHPFX/PD0y1YztEcJi3u25Ajxw3AN3RDG8c/UNRrHYPWl9XzM0eb3NT9crmbo+uEkM1dnlPEwfJPJDsLQOX5Y0Yd3242MJVEgXnK+y3h4h5qhNR42BRYdOULmpeFiYj+sZrX2LPwotGFzXtpWCTxJsZqhNS9tCyzacoQndQ8BzpEz0+wajyMtkR4kQNtgwwBtgw0DAAAAQOsQe2jCFx9ohrvGHlb95nJl7KF9Ot+WoBq3ij0Uq0v0MopTXBp7aJ7OGg+owo1jD+fMq7ioW8Qe7j0SoJhbxh76qfu5R+yhOp2YB6jJLWMPN6Mpmoo9TE4n9hBqcsfYw4pj4bvEHqrT8cNQk9vFHhYZcHOxh7uPBNjmjrGHVT3wzJWxh+bpzEvDh7g+9jAuQa0u5pWxh/bpfB+GT0DsIQAUgw0DtA02DAAAAAAAAAAAAAAAAAAAAFDKsoQy0vd6QiIAAAAAAAAAAAAAAAAAAABAQ0T7pIbR2Khyg9q6h3KT2FsjFKr2JFbaw8S80NdOh/ugd8Jbt6CN96DN7Il3VPewcG/H6Nr1JRZzV083+1yPNjd3L0h0bNhZTeaVM7mQLcW4VkNny870v0Nsw8u+x33vHyaSj9tU6bkf2Xrr0A7PuiRmd6EkMVuhdP95u5zxhWwpxjmTMYQx6Rhgw62zud1s5HPq6h6+bE9gSRt9wob3iCHKk2IJJek4ixOzmo+6tn454wv52hF9+Au9SPH6NWx53ShRUzU1Ht7H1dU9nK5tGmfqtqy3yhl2iCF6pTrnh33NR1W0jDJTqR+enmj8IkzKKUvSD4yR26EPb1GDt/BQgnyZ19U9XEaahhVn+nm56+4QYSoXQ8wU6pQNu5qPsQvNldMa9erCL7lt2DBd61bphjAMIfSvru/XprGqliiFwLq6h6sgUarJm21QVeZiMv7NeU+UOObSRHn1JN+jftiSYtQdjA0bZn66QbTq8Jo6SjHAmcq6h9HwLPS55hkVxPvbDj9cLoaYKdEX/HBmlJs3wvd56aS6957EDzfJNOgxbHiVC1vcc3XdQ/mxQ0+UxQ1KSQeeUEtNrl8mhpgWKJtadzxcPi+dTDZmXw2Mh3+KaLLqbxy6taM7DF162CaFc1qrlwj9ZNK28KFMrecs0mlYRwzRm3s715c25qV17WXH2Kh7eiFbilFeM/9tiXnpVnm7uT78mdvXpA3JgccOAAAAAAAAAABfg9jD48wzfU3GHsLPcP/Yw3e5qk+Al1297djDXeENfFtqlfvHHur1C5XWHzwj9tC+kpnnoRsC17L5yTfyOcv6pW/HHn4iWv0hsYemDZtH+os64e7cP/ZQtvha/Tw3lkDU7RdiD5W129EP7zyzQSBwaxqIPeyDsNx4aXVyWa8fkVz7GbGH0R/XTKI8rUTjvsHtaCL28BMuIpvnD8UeJnXwXC5+uE1aiT1UgUvEHrp5bt6lKZHx8M/QSuyhal+5vvQuHhF76IRtMi/9YzQQe6i+0lbr46WfQ38w9tAJ2+T78E9B7CEAAAAAAAAAALQGsYfHmWf6iD2EK2kh9lBe/YPfliweFHu4Vpi3QlvcP/bQXM1/FmIPjTxfL0MhEe7L5iffyOcs65cujT2s1A8l9tC6XB8pJEIT3D/28BN+2F1dLOr2qNjD6Q+hd+we7ksDsYfy4Kzb3xHzQOxhkudyXWy4KZqIPSyJqttLNsrnibGH2h1jw63QSOxh1t6iPEv9MLGH0Xnp9Dt7ADRAK7GHyTRalYlpYg+NPK0CwP1pIfbQiqo7TfqN9OGxh7J02HBLEHsIAAAAAAAAAACtccPYw7aZp/8ISIQvcWHsoc2l3zZyH11WfjEgUaTGy7D58nBzros9dLjQhp8bkNitsS5ytQibTt+bzU++kXtZ1i9Vij0U17dWJKjLy1URa98zPv0sTw5INO/DJ6I+oTpXxR4qj6FWbDpuIl2CYp9+HHfJsajwrwYkSpbLF69Uhyu5LPbQCa15+TacmEqRV9gRCPHkgEQzxbpQmgVcyoWxhy9pXvFs7UZfMnv6qfI8NiDxZR2DH749V8YeRnlH8zJFNuycHrHDDz86IPFlGTnj4ZtzbeyhODHTmEVa7Ji808/w4IBE20szL90El8UeOh8kX2J6Ws9Lp53WLce6n/Rz6DMCEnNfBOrfZagLsYcAAAAAAAAAAM3xz/r36/wHuIDR10rVC5YAAAAASUVORK5CYII=" alt="" />
由此可见,栈区从高地址向低地址生成,而堆区正好相反,栈区和堆区之间并没有严格的分解,可以进行动态微调
0x2: 内存管理接口
从底层硬件到上层应用,各层都提供了各自的内存管理接口
aaarticlea/png;base64,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" alt="" />
Relevant Link:
http://www.cnblogs.com/dejavu/archive/2012/08/13/2627498.html
0x3: 虚拟内存管理技术
Unix/Linux系统中的内存都是采用虚拟内存管理技术进行管理的,即每个进程都有0~4G的内存地址(虚拟的),由操作系统负责把虚拟内存地址和真实的物理内存映射起来,因此,不同的进程中虚拟地址空间看起来是相同的,但是对应的实际物理内存是不同的
0x4: 用户空间与内核空间
4GB的虚拟进程地址空间分成两部分
. ~ 3G-: 用户空间,存放用户程序的代码和数据
. 3G ~ 4G-: 内核空间,存放系统内核的代码和数据
. 用户空间的代码不能直接访问内核空间的代码和数据,但可以通过系统调用进入内核态,间接地与系统内核交互
0x5: 内存壁垒与段错误
. 每个进程的用户空间都是0 ~ 3G-,但它们所对应的物理内存却是各自独立的,系统为每个进程的用户空间维护一张专属于该进程的内存映射表,记录虚拟内存到物理内存的对应关系,因此在不同进程之间交换虚拟内存地址无意义的(刻舟求剑)
. 所有进程的内核空间都是3G ~ 4G-,它们所对应的物理内存只有一份,系统为所有进程的内核空间维护一张内存映射表: init_mm.pgd,记录虚拟内存到物理内存的对应关系,因此不同进程通过系统调用所访问的内核代码和数据是同一份
. 用户空间的内存映射表会随着进程的切换而切换,内核空间的内存映射表则无需随着进程的切换为切换
. 一切对虚拟内存的越权访问,豆浆导致段错误
) 试图访问没有映射到物理内存的虚拟内存
) 试图以非法方式访问虚拟内存,如对只读内存读写操作等
. 内存地址的基本单位是字节,但是内存映射的基本单位是内存页,目前主流的操作系统的内存页大小是4Kb(4096字节)
常见导致段错误原因
. 野指针/空指针使用
int* pi; //野指针
int* pi = NULL; //空指针
scanf("%d", pi); . 使用未映射的虚拟地址
. 对没有操作权限的内存进行操作
) 对只读常量区进行写操作,可能引发段错误
0x6: 标准C内存分配函数(Glibc封装的函数)
. 标准库提供的内存分配函数(malloc/calloc/realloc)在标准库内部维护一个线性链表,管理堆中动态分配的内存
. 标准内存分配函数在分配内存时会附加若干(通常是12字节),存放控制信息(MCB 内存控制块),该信息一旦被意外损坏,可能在后续操作中引发异常
. 虚拟内存到物理内存的映射以页(4K=4096bytes)为单位
#include <unistd.h>
int getpagesize(void); . 通过malloc函数首次分配内存,至少映射33页,即使通过free函数释放掉全部内存,最初的33页仍然保留
aaarticlea/png;base64,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" alt="" />
看以下代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> int main(void){
uint64_t* p1 = (uint64_t*)malloc(sizeof(uint64_t));
uint64_t* p2 = (uint64_t*)malloc(sizeof(uint64_t));
uint64_t* p3 = (uint64_t*)malloc(sizeof(uint64_t));
uint64_t* p4 = (uint64_t*)malloc(sizeof(uint64_t));
uint64_t* p5 = (uint64_t*)malloc(sizeof(uint64_t)); printf("p1 = %p\n", p1);
printf("p2 = %p\n", p2);
printf("p3 = %p\n", p3);
printf("p4 = %p\n", p4);
printf("p5 = %p\n", p5);
printf("------------\n"); *p1 = ;
*(p1+) = ;
*(p1+) = ;
*(p1+) = ;
*(p1+) = ; printf("*p1 = %ld, *p2 = %ld\n", *p1, *p2); free(p1);
free(p2);
free(p3);
free(p4);
free(p5);
return ;
}
aaarticlea/png;base64,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" alt="" />
0x7: malloc/free的简化实现
1. 内存控制块
内存控制块用于管理每次分配的内存块,记录该内存块的字节大小(即传入malloc的size参数)、忙闲状态,以及相邻内存控制块的首地址(链式结构)
typedef struct mem_control_block{
size_t size; //块大小
bool freel //空闲标志
struct mem_control_block* next; //后块指针
} MCB;
aaarticlea/png;base64,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" alt="" />
2. 单向链表栈(以链表方式存储的栈结构)
多次堆内存分配会产生多个内存控制块(每次通过malloc申请的内存都会对应一个MCB),可将其组织成链表栈的形式以便于集中管理,可由栈顶指针遍历该链表
MCB* g_top = NULL;
MCB* mcb;
for(mcb = g_top; mcb; mcb = mcb->next)
..
aaarticlea/png;base64,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" alt="" />
3. 分配内存
遍历内存控制块链表,若有大小足够的空闲块,则重用该块,否则分配新的足量内存并将其控制块(每块内存的头部都有一个MCB)压入链表栈,通过MCB链表栈
4. 释放内存
先将被释放内存块标记为空闲,然后遍历内存控制块链表,将靠近栈顶的连续空闲块及其内存控制块一并释放
5. size命令
. 通过size命令可以观察特定可执行程序的代码区(text)、数据区(data)、BSS区(bss)的大小,以字节为单位
. 符合ELF标准的可执行程序文件只包含代码区、数据区的内容,在进程加载阶段被exec函数读入进程的内存空间
6. 代码示例
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h> typedef struct mem_control_block{
size_t size;
bool free;
struct mem_control_block* next;
} MCB;
MCB* g_top = NULL; void* my_malloc(size_t size){
MCB* mcb;
for(mcb= g_top; mcb; mcb = mcb->next){
if(mcb->free && mcb->size >= size){
break;
}
}
if(!mcb){
mcb = sbrk(sizeof(MCB) + size);
if((void*)- == mcb)
return NULL;
mcb->size = size;
mcb->next = g_top;
g_top = mcb;
}
mcb->free = false;
return mcb + ;
} void my_free(void* ptr){
if(ptr){
MCB* mcb = (MCB*)ptr - ;
mcb->free = true;
//because mcb single way link stack, we need loop from the start
for(mcb = g_top; mcb->next; mcb = mcb->next){
if(!mcb->free)
break;
}
//当内存控制块链表中只有一个结点时,删除该节点
if(mcb->free){
g_top = mcb->next;
brk(mcb);
}
//mcb是栈结构,头指针从栈顶一直遍历过一段连续的空闲块空间,然后一次性释放这段内存
else if(mcb != g_top){
g_top = mcb;
brk((void*)mcb + sizeof(MCB) + mcb->size);
}
}
} int main()
{
printf("1\n");
int *p = my_malloc(sizeof(int));
printf("2\n");
*p = ;
printf("3\n");
printf("%d\n", *p);
printf("4\n");
my_free(p);
return ;
}
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWwAAABdCAIAAAAOrMtSAAAFkUlEQVR4nO3d2aHjIAxA0fTkdijGvVALpbiP+fAmQAIMeY6TuedrHuONTRbO9nrh4PwS5qm0xTSHZVmW2mZIOb8sy+LdDaf6pT5amy11SzMCAADAMs3hbSnZnrxG6ata+Bdnx6a+EvxW1wfYu874ow1aMM2hs9Jnh0T9IorFlBel0enUQfypkW3UqPdQZ/X7G/mN1CA81NTOGzP0/bG++w5y3wBz/r+9x6njWw8E5aOs3TLNYd/jKHu9nD/PEQ+HRwURSVx9h6QGTwgieqMONLXzwfuzXuJI8UH3ystBcP1cvZd52wD75kR5mkOYZx/dOo8YkAzkpDB9hLw1gZw+zm/Fx95aO1kTTo/N0Yxq62P97Hup92L7Yt23Lac5hBD2Ai3jGAshsuJGI5/F0Wm03sxz8GirqC3tDCruC63ptN3jnpB/Ob94J7oyOn7SxVsM6Z9j+752x5l1bwwi6rBpza2SDFaOxYbeNAvvM81BqflaZ9FWauH2H8be+Z9GsLXiunnv68tEzCsTWXW97lsQWbw7IkV+OmOQNU6CPO8oZCLZuicdR0pFxMWoXZIXxhegNp2+exY3jk22C5Fx7TzOuqnyQmfPHInOUu64vO5NA0yfHdG/59qFKz3R1ptG4Z2ysyZDIB9r2T0pfUghU48QakGkEELUhyLxAbqDiDrSW+q+ZSLi5qg0gTo25aXv8+PI3uZSXCwtZ6LNi715HMea5WYNsvVF++7nv89xc1TnrNfRsGuTnHtl4eayeIqVOk6rUUv7VIdNCyOIXOvND618s5PKAjm71ACb7S+6aX/GUQwiRggpLAfim99IEGmsZl5YHIst6+UzZmzBJN5fSw2s9DneW+vN5F6+3om13jSOmV3Std23LUTrK9FEz0RecqIMxBA5AI2OK9W9JYiUh00LPYi09WZeeC/1QvszkTSIpH0YV9Ce7aX2l4d8WiYy+shNH3qlNWOaidi3BLXQqnslMNWaLr3NuCiGKGuU/JnI/I7FTLYOUzuukFt9OBO52Jsfot/kLj0TSdeQ8ZPUxQwiyYLl3CZtk+i5fLyB2lV6/yWlUY1E8tz2TEQPImqNjmM0jKlCYpbkAnJKFiZ8ckjnzahnHVNfXWVNZ17SMRSU2hvhN1sCadmZIm9kI2UoBBHt4qsDTJ8d73gm0tCbRuGdtDh2BABlKOS3g+POogaZZBuxaX5HUp6lnXmvla0lTxe0wspBu16d0caiWiNxhGrv2pMlaWTxty9mDUnjRWuE/UBi7ubH1C9JazrjkkqVz/KEpNnOBm6aGNl50ou3U0j74lsGmDU78hqVL74eRPS7s174zRpvug/SvgZpvCX2eUBemnrPJV3N7N/kge2JC8578jdEk1oQmWZ/ZNcMy8s+FEOAG9Vjw54uEkIucvd9FcDz5ctdGgcAAAAAPsd83RYA2vFaGIAhBBEAQwgiAIYQRAAMIYgAGEIQATCEIAKgV/x2ft7GDwAAAAAAAAAAAADP9XPfEg3gTuKr+Gs/GAUAFX/6awgAfh6/hgBggP37jwBQw/MQAP2IIAD6EUEAjEh/1o+nIgAAAAAAAAAAAADwZOK7AHjDCICrnD8jxzQH3igCYAA/YQVgBB/kBdDjeChCAAEwxHmerQIYwhckArhGvjjD1wIA6CDeJsJTEQAAAAAAAAAAAAB4tuMl3vgdIucrv7zsC6Au+fyu+FlefqEXQIM4iETvfuf7AQDURZEiT0tY0gAoi+LGuoKZ5rA+EHF+CfMnLw7A85GJABjCMxEAQ3h1BkAv55cl/zIA3icCAAAAAAAAAAAAAM/FL1cBGOB88J53pgLo4/ziHW9vB9BnmoN3fEYGQJ8jdhBEAHQ4P7BLEAFwXfzpu/X7mj99TQC+E5kIgCEEEQAAAAAAAAAAgL/0Dw8S+JuJGI8kAAAAAElFTkSuQmCC" alt="" />
0x8: UnixC(系统调用)的内存分配函数
1. sbrk函数: 主要用于调整所申请堆内存的大小
#include <unistd.h>
void *sbrk(intptr_t increment);
) increment > : 申请内存空间
) increment < : 释放内存空间
) increment = : 获取内存空间当前位置
返回值
) 成功: 返回调整内存大小之前的位置(即上次调用sbrk/brk后的堆尾指针)
) 失败: (void*)-
系统内ubweihu一个指针,指向当前堆尾,即堆区最后一个字节的下一个位置,sbrk函数根据增量参数调整该指针的位置,同时返回该指针调整前的位置,其间若发生内存页耗尽(OOM)或空闲,则自动追加或取消内存页的映射,使用sbrk申请内存时,不会申请额外的空间存储管理内存的相关元信息
aaarticlea/png;base64,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" alt="" />
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(void){
void* p1 = sbrk();
void* p2 = sbrk();
void* p3 = sbrk();
printf("p1 = %p, p2 = %p, p3 = %p\n", p1, p2, p3); void* cur = sbrk();
printf("cur = %p\n", cur); void* p4 = sbrk(-);
printf("p4 = %p\n", p4);
return ;
}
aaarticlea/png;base64,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" alt="" />
2. brk函数: 主要用于根据参数指定的目标位置调整内存大小
int brk(void *addr);
. 目标位置 > 之前的目标位置: 申请内存
. 目标位置 < 之前的目标位置: 释放内存
. 目标位置 = 之前的目标位置: 内存不变
系统内部维护一个指针,指向当前堆尾,即堆区最后一个字节的下一个位置,brk函数根据指针参数设置该指针的位置,其间若发现内存页耗尽或空闲,则自动追加或取消内存页的映射
aaarticlea/png;base64,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" alt="" />
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(void){
void* p = sbrk();
brk(p + ); void* p2 = sbrk();
printf("p = %p, p2 = %p\n", p, p2); brk(p+);
p2 = sbrk();
printf("p = %p, p2 = %p\n", p, p2); brk(p);
p2 = sbrk();
printf("p = %p, p2 = %p\n", p, p2);
return ;
}
aaarticlea/png;base64,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" alt="" />
使用brk函数释放内存比较方便,因此我们使用brk和sbrk函数搭配使用
. UnixC的brk和sbrk更加本质的揭示了堆内存的管理本质,即一段连续的内存空间,我们熟悉的glibc malloc/free是在brk和sbrk的基础上在内部维护了一套数据结构,使用MCB链表栈的形式进行堆内存管理,并向上层用户提供内存池 . 使用sbrk函数负责申请内存、使用brk函数负责释放内存
. sbrk和brk本质上是移动堆尾指针的两种不同方法,移动过程中还要兼顾虚拟内存和物理内存之间映射关系的建立和解除(以页为单位)
. 用sbrk分配内存比较方便,用多少内存就传多少增量参数,同时返回指向新分配内存区域的指针,但是用sbrk做一次性内存释放比较麻烦,因为必须将所有的既往增量进行累加
. 用brk释放内存比较方便,只需将堆尾指针设回到一开始的位置即可一次性释放掉之前分多次分配的内存,但用brk分配内存比较麻烦,因为必须根据所需要的内存大小计算出堆尾指针的绝对位置
. 最佳实践: 用sbrk分多次分配适量内存,最后用brk一次性整体释放
0x9: 内存映射的建立与解除
1. 建立内存映射
在当前进程的虚拟地址空间中建立虚拟内存到物理内存或文件的映射
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
. addr: 映射区内存起始地址,传入NULL则系统自动选定后返回(推荐传入NULL)
. length: 映射区字节长度,自动按页(4K)取整
. prot: 映射区访问权限,可取以下值(可按位或)
) PROT_EXEC: Pages may be executed.
) PROT_READ: Pages may be read.
) PROT_WRITE: Pages may be written.
) PROT_NONE: Pages may not be accessed.
. flags: 映射标志,可取以下值
) MAP_SHARED: Share this mapping. 对映射区的写操作直接反映到文件中
) MAP_PRIVATE: Create a private copy-on-write mapping. 对映射区的写操作只反应到内存缓冲区中,并不会真正写入文件
) MAP_ANONYMOUS: The mapping is not backed by any file; its contents are initialized to zero. 匿名映射,将虚拟内存映射到物理内存而非文件,忽略fd和offset参数 ) MAP_32BIT (since Linux 2.4., 2.6): Put the mapping into the first Gigabytes of the process address space.
) MAP_FIXED: Don't interpret addr as a hint: place the mapping at exactly that address. 若在start上无法创建映射,则失败(如果无此标志则系统会自动调整)
) MAP_GROWSDOWN: Used for stacks. Indicates to the kernel virtual memory system that the mapping should extend downward in memory.
) MAP_HUGETLB (since Linux 2.6.): Allocate the mapping using "huge pages."
) MAP_LOCKED (since Linux 2.5.): Lock the pages of the mapped region into memory in the manner of mlock().锁定映射区,保证其不被swap换出
) MAP_NONBLOCK (since Linux 2.5.): Only meaningful in conjunction with MAP_POPULATE. Don't perform read-ahead: create page tables entries only for pages that are already present in RAM.
) MAP_NORESERVE: Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available.
) MAP_POPULATE (since Linux 2.5.): Populate (prefault) page tables for a mapping. For a file mapping, this causes read-ahead on the file. Later accesses to the mapping will not be blocked by page faults.
) MAP_STACK (since Linux 2.6.): Allocate the mapping at an address suitable for a process or thread stack.
) MAP_UNINITIALIZED (since Linux 2.6.): Don't clear anonymous pages. This flag is intended to improve performance on embedded devices.
. fd: 文件描述符,单纯把mmap用作内存映射(申请一段可用的虚拟内存)时,传入0即可
. offset: 文件偏移量,自动按页(4K)对齐,单纯把mmap用作内存映射(申请一段可用的虚拟内存)时,传入0即可
2. 解除内存映射
解除虚拟内存到物理内存或文件的映射
#include <sys/mman.h>
int munmap(void *addr, size_t length);
. addr: 映射区内存起始地址,必须是页的首地址
. length: 映射区字节长度,自动按页(4K)取整
需要注意的是
. mmap/munmap底层不维护任何数据结构,只是返回一个首地址,所分配的虚拟内存位于堆中
. brk/sbrk底层维护一个指针,记录所分配的内存结尾,所分配的虚拟内存位于堆中,底层调用的就是mmap/munmap
. malloc底层维护一个线性链表和MCB控制信息,不可越界访问,所分配的虚拟内存位于堆中,底层调用的就是brk/sbrk
. 每个进程都有4G的虚拟内存空间,虚拟内存地址只是一个数字,在于实际物理内存建立映射之前是不能访问的
. 所谓内存分配与释放,其本质就是建立或解除从虚拟内存到物理内存的映射,并在底层维护不同形式的数据结构,以把虚拟内存的占用与空闲情况记录下来
3. 示例代码
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h> int main(){
char* p = (char*)mmap(
NULL,
,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
, );
if(p == MAP_FAILED){
perror("mmap");
exit(EXIT_FAILURE);
}
strcpy(p, "hello, memory!");
printf("%s\n", p); if(- == munmap(p, )){
perror("munmap");
exit(EXIT_FAILURE);
}
strcpy(p += , "hello memory twice");
printf("%s\n", p);
if(- == munmap(p, )){
perror("munmap");
exit(EXIT_FAILURE);
} return ;
}
10. 系统调用
0x1: Unix应用的层次结构
. Unix/Linux系统的大部分功能都是通过系统调用实现的,如open、close等
. Unix/Linux的系统调用已经被封装成C函数的形式,但它们并不是C语言标准库的一部分
. 标准库函数大部分时间运行在用户态,但部分函数偶尔也会调用系统调用,进入内核态,如malloc、free等
. 我们自己编写的代码也可以跳过标准库,直接使用系统调用,如brk、sbrk、mmap、munmap等,与操作系统内核交互,进入内核态
. 系统调用在内核中实现,其外部接口定义在C库中,该接口的实现借助软中断进入内核
aaarticlea/png;base64,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" alt="" />
11. 文件管理(Unix C)
0x1: 文件的打开与关闭
文件在使用之前需要将其打开才能使用,打开文件时,系统会为其在内核中维护一套专门的数据结构,保存该文件的信息。而当文件不再使用之后,需要将其关闭,并删除在内核中专门的数据结构
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> int main(){
long openmax = sysconf(_SC_OPEN_MAX);
printf("一个进程最多能持有%ld个处于打开状态的文件描述符\n", openmax); int fd = open("open.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x2: I/O重定向
为了解决内核对象在可访问性与安全性之间的矛盾,Unix系统通过所谓的文件描述符,将位于内核空间中的文件表项间接地提供给运行于用户空间中的程序代码。
为了便于管理在系统中运行的各个进程,内核会维护一张存有各进程信息的列表,谓之进程表。系统中的每个进程在进程表中都占有一个表项。每个进程表项都包含了针对特定进程的描述信息,如进程ID、用户ID、组ID等,其中也包含了一个被称为文件描述符表的数据结构。
文件描述符表的每个表项都至少包含两个数据项——文件描述符标志和文件表项指针,而所谓文件描述符,其实就是文件描述符表项在文件描述符表中从0开始的下标。
系统内核缺省为每个进程打开三个文件描述符,它们在unistd.h头文件中被定义为三个宏
#define STDIN_FILENO 0 // 标准输入,一般从键盘输入
#define STDOUT_FILENO 1 // 标准输出,一般输出到显示器
#define STDERR_FILENO 2 // 标准错误,一般输出到显示器
//可以通过控制台命令改变上面三个文件描述符的I/O定向
#include <stdio.h>
#include <string.h> int main(){
char buf[];
scanf("%s", buf);
printf("%s\n", buf); strcpy(buf, "标准输出已被I/O重定向为输出到文件o.txt");
printf("%s\n", buf); return ;
}
./ioredirect 0<i.txt 1>o.txt
. ./ioredirect: 可执行文件名
. <i.txt: 关闭文件描述符0,打开i.txt,该文件获得文件描述符0,即代码中的scanf函数从i.txt文件中输入内容
. >o.txt: 关闭文件描述符1,打开o.txt,该文件获得文件描述符1,即代码中的printf函数将内容输出到o.txt
aaarticlea/png;base64,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" alt="" />
0x3: 写入文件
文件被打开后,就可以向其中写入字节流,并在不使用文件时需要将文件关闭
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} char text[] = "将这些内容写入到文件中";
size_t towrite = strlen(text);
ssize_t written = write(fd, text, towrite);
if(- == written){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x4: 读取文件
文件被打开后,就可以从其中读出字节流,注意在不使用文件时需要将文件关闭
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h> int main(){
int fd = open("data.txt", O_RDONLY, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} char text[] = {};
size_t toread = ;
ssize_t readed = read(fd, text, toread);
if(- == readed){
perror("read");
exit(EXIT_FAILURE);
}
printf("%s\n", text); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x5: 二进制读写
基于系统调用的文件读写本来就是面向二进制字节流的,因此对二进制读写而言,无需做任何额外的工作
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h> typedef struct Employee{
char name[];
int age;
float salary;
} EMP; int main(){
//write binary data
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} EMP emp = {"赵云", , };
if(- == write(fd, &emp, sizeof(emp))){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} //read binary data
fd = open("data.txt", O_RDONLY, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} EMP emp_read = {};
if(- == read(fd, &emp_read, sizeof(emp))){
perror("read");
exit(EXIT_FAILURE);
}
printf("%s,%d,%f", emp_read.name, emp_read.age, emp_read.salary); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x6: 文本读写
因为基于系统调用(Unix C)的文件读写是面向二进制字节流的,因此对写入内容的格式化、以及对读取内容的解格式化,都必须通过自己编写的代码进行处理(自己构造出一个字符串)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h> typedef struct Employee{
char name[];
int age;
float salary;
} EMP; int main(){
//write ascii data
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} EMP emp_write = {"赵云", , };
char buf[] = {};
sprintf(buf, "%s %d %0.2f", emp_write.name, emp_write.age, emp_write.salary);
if(- == write(fd, buf, strlen(buf))){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} //read ascii data
fd = open("data.txt", O_RDONLY, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} EMP emp_read = {};
memset(buf, 0x0, sizeof(buf) / sizeof(buf[]));
if(- == read(fd, buf, )){
perror("read");
exit(EXIT_FAILURE);
}
sscanf(buf, "%s%d%f", emp_read.name, &emp_read.age, &emp_read.salary);
printf("%s,%d,%f\n", emp_read.name, emp_read.age, emp_read.salary); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x7: 顺序与随机读写
1. 文件读写位置
. 每个打开的文件都有一个与其相关的文件读写位置保存在文件表项中,用以记录从文件头开始计算的字节偏移
. 文件读写位置通常是一个非负的整数,用off_t类型表示,在32位系统上被定义为long int,而在64位系统上则被定义为long long int
. 打开一个文件时,除非指定了O_APPEND标志,否则文件读写位置一律被设置为0,即文件首字节的位置
2. 顺序读写
. 每一次读写操作都从当前的文件读写位置开始,并根据所读写的字节数,同步增加文件读写位置,为下一次读写做好准备
. 因为文件读写位置是保存在文件表项而不是v节点中的,因此通过多次打开同一个文件得到多个文件描述符,各自拥有文件读写位置
3. 随机读写
. 人为调整文件读写位置
4. 文件空洞
. 可以通过lseek函数将文件读写位置设置到文件尾之后
. 在超过文件尾的位置上写入数据,将在文件中形成空洞,位于文件中但没有被写过的字节都被设置为0
. 文件空洞不占用磁盘空间,但被计算在文件大小之内
aaarticlea/png;base64,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" alt="" />
5. 示例代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h> typedef struct Employee{
char name[];
int age;
float salary;
} EMP; int main(){
//write ascii data
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} EMP emp_write = {"赵云", , };
char buf[] = {};
sprintf(buf, "%s %d %0.2f", emp_write.name, emp_write.age, emp_write.salary);
if(- == write(fd, buf, strlen(buf))){
perror("write");
exit(EXIT_FAILURE);
} //set the point to the start of this file
lseek(fd, , SEEK_SET); EMP emp_read = {};
memset(buf, 0x0, sizeof(buf) / sizeof(buf[]));
if(- == read(fd, buf, )){
perror("read");
exit(EXIT_FAILURE);
}
sscanf(buf, "%s%d%f", emp_read.name, &emp_read.age, &emp_read.salary);
printf("%s,%d,%f\n", emp_read.name, emp_read.age, emp_read.salary); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x8: 复制文件描述符
1. dup
复制文件描述符表项
#include <unistd.h>
int dup(oldfd);
. dup函数将oldfd参数所对应的文件描述符表项复制到文件描述符表的第一个空闲项中,同时返回该表项所对应的文件描述符
. dup函数返回的文件描述符一定是调用进程当前未使用的最小文件描述符
. dup函数只复制文件描述符表项,不复制文件表项和v节点,因此该函数所返回的文件描述符可以看作是参数oldfd的副本,它们标识同一个文件表项
aaarticlea/png;base64,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" alt="" />
需要注意的是,当关闭文件时,即使是由dup函数产生的文件描述符副本,也应该通过close函数关闭,因为只有当关联于一个文件表项的所有文件描述符(指向文件表项的指针)都被关闭了,该文件表项才会被销毁
由dup函数返回的文件描述符与作为参数传递给该函数的文件描述符标识的是同一个文件表项,而文件读写位置是保存在文件表项而非文件描述符表项中,因此通过这些复制出来的/或者原始的文件描述符中的任何一个,对文件进行读写或随机访问,都会影响通过其他文件描述符操作的文件读写位置,这与多次通过open函数打开同一个文件不同
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> int main(){
int fd = open("dup.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} char buf[] = "old fd's content";
if(- == write(fd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} int newfd = dup(fd);
strcpy(buf, "dup's fd's content");
if(- == write(newfd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
}
if(- == close(newfd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
2. dup2
复制文件描述符表项到指定位置
#include <unistd.h>
int dup2(int oldfd, int newfd);
. dup2函数的功能与dup函数几乎完全一样,唯一不同就是允许调用者通过newfd参数指定目标文件描述符(dup的newfd是系统自动指定的),正常情况下该函数的返回值应该与newfd参数的值相等
. dup2函数在复制由oldfd参数所标识的源文件描述符表项时,会首先检查由newfd参数所表示的目标文件描述符表项是否空闲,若空闲则直接将oldfd复制给newfd,否则会先将指定的目标文件描述符newfd关闭,再进行复制
示例代码
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> int main(){
int fd = open("dup2.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} char buf[] = "this is origin file's content";
if(- == write(fd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} int newfd = dup2(STDOUT_FILENO, fd);
strcpy(buf, "after dup2, this content will be displayed into console");
if(- == write(newfd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} //can't do it, fd has already be closed
/*
if(-1 == close(fd)){
perror("close");
exit(EXIT_FAILURE);
}
*/
if(- == close(newfd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
dup/dup2函数用于复制文件描述符时,实质上是复制文件描述符所对应的文件表地址指针,也就是让多个文件描述符对应了同一个文件表,从而对应同一个文件
0x9: 文件控制
1. 复制文件描述符
#include <fcntl.h>
int fcntl(int oldfd, int cmd, int newfd);
. oldfd: 源文件描述符
. cmd: 控制命令: 取F_DUPFD
. newfd: 目标文件描述符
fcntl(F_DUPFD)的功能与dup2函数几乎完全一样,唯一不同就是当目标文件描述符newfd处于打开状态时,并不关闭它,而是继续往下找一个大于等于指定值的fd作为目标
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> int main(){
int fd = open("fcntl.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} char buf[] = "this is old fd's content";
if(- == write(fd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} int newfd = fcntl(STDOUT_FILENO, F_DUPFD, fd);
strcpy(buf, "this is fcntl' fd's content, but i will display in console");
if(- == write(newfd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} if(- == write(newfd, buf, strlen(buf) * sizeof(buf[]))){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
}
if(- == close(newfd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
2. 获取/设置文件描述符标志
. 文件描述符表的每个表项都至少包含来年哥哥数据项
) 文件描述符标志: 用于表示特定文件描述符的属性
) 文件表项指针
. 文件描述符标志由多个二进制位组合而成,每个二进制位表示某一方面的属性
获取文件描述符标志
#include <fcntl.h>
int fcntl(int fd, int cmd);
. fd: 文件描述符
. cmd: 控制指令,去F_GETFD
设置文件描述符标志
#include <fcntl.h>
int fcntl(int fd, int cmd, int flags);
. fd: 文件描述符
. cmd: 控制命令,取F_SETFD
. flags: 文件描述符标志
3. 获取/设置文件状态标志
由文件状态标志是由open函数的flags参数设定的,用于表示特定文件描述符的状态保存在文件表项中
文件状态标志由多个二进制位组合而成,每个二进制位表示某一方面的状态,包括
. O_RDONLY - 只读 O_WRONLY - 只写 O_RDWR - 读写 O_APPEND - 追加
. O_CREAT - 创建 O_EXCL - 排斥 O_TRUNC - 清空 O_SYNC - 同步
. O_ASYNC - 异步 O_NONBLOCK - 非阻塞
获取文件状态标志
#include <fcntl.h>
int fcntl(int fd, int cmd);
. fd: 文件描述符
. cmd: 控制指令,取F_GETFL
示例代码
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} int flags = fcntl(fd, F_GETFL);
if((flags & O_ACCMODE) == O_RDONLY)
printf("read only\n");
if(flags & O_WRONLY)
printf("write only\n");
if(flags & O_RDWR)
printf("read write\n");
if(flags & O_APPEND)
printf("append\n");
if(flags & O_SYNC)
printf("sync\n");
if(flags & O_ASYNC)
printf("async\n");
if(flags & O_NONBLOCK)
printf("no block"); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
追加文件状态标志
#include <fcntl.h>
int fcntl(int fd, int cmd);
. fd: 文件描述符
. cmd: 控制指令,取F_SETFL
示例代码
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> int main(){
int fd = open ("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if (fd == -){
perror ("open");
exit (EXIT_FAILURE);
}
int flags = fcntl(fd, F_GETFL);
if (flags & O_APPEND)
printf ("1.追加\n");
if (flags & O_NONBLOCK)
printf ("1.非阻塞\n"); if (fcntl (fd, F_SETFL, O_APPEND | O_NONBLOCK) == -){
perror ("fcntl");
exit (EXIT_FAILURE);
}
flags = fcntl(fd, F_GETFL);
if (flags & O_APPEND)
printf ("2.追加\n");
if (flags & O_NONBLOCK)
printf ("2.非阻塞\n");
if (close (fd) == -){
perror ("close");
exit (EXIT_FAILURE);
} return ;
}
0x10: 文件锁
如果两个或两个以上的进程同时向一个文件的某个特定区域写入数据,那么最后写入文件的数据极有可能因为写操作的交错而产生混乱
aaarticlea/png;base64,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" alt="" />
aaarticlea/png;base64,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" alt="" />
1. 读锁和写锁
. 为了避免多个进程在读写同一个文件的同一个区域时发生冲突,Unix/Linux系统引入了文件锁机制,并把文件锁分为读锁和写锁两种
) 读锁: 共享锁,对一个文件的特定区域可以加多把读锁
) 写锁: 排它锁,对一个文件的特定区域只能加一把写锁
. 基于锁的操作模型是: 读/写文件中的特定区域之前,先加入读/写锁,锁成功了再读/写,读/写完成以后再解锁
2. 加锁和解锁
对给定文件的特定区域加锁或解锁
#include <fcntl.h>
int fcntl(int fd, int cmd, struct flock* lock);
. fd: 文件描述符
. cmd: 控制指令,可取以下值
) F_SETLKW: 阻塞模式
) F_SETLK: 非阻塞模式
. lock: 决定是加锁还是解锁,若因其他进程持有锁而导致枷锁失败
) 阻塞模式下: 返回-
) 非阻塞模式下: 返回-,并设置错误码为EAGANIN
需要注意的是
. 当通过close函数关闭文件描述符时,调用进程在该文件描述符上所加的一切锁将被自动解除
. 当进程终止时,该进程在所有文件描述符上所加的一切锁将被自动解除
. 文件锁仅在不同进程之间起作用,同一个进程的不同线程不同通过文件锁解决读写冲突问题
. 通过fork、vfork函数创建的子进程,不继承父进程所加的任何文件锁
. 通过exec函数族创建的新进程,会继承调用进程所加的全部文件锁,除非某文件描述符带有FD_CLOEXEC标志
示例代码: 从文件头10字节开始的20字节以阻塞模式加读锁
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = ;
lock.l_len = ;
lock.l_pid = -;
if(- == fcntl(fd, F_SETLKW, &lock)){
perror("fcntl");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
示例代码: 从当前位置10字节开始到文件尾以非阻塞模式加写锁
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_CUR;
lock.l_start = ;
lock.l_len = ;
lock.l_pid = -;
if(- == fcntl(fd, F_SETLK, &lock)){
if(EAGAIN != errno){
perror("fcntl");
exit(EXIT_FAILURE);
}
printf("waiting\n");
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
示例代码: 对整个文件解锁
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = ;
lock.l_len = ;
lock.l_pid = -;
if(- == fcntl(fd, F_SETLKW, &lock)){
perror("fcntl");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
文件锁是一种建议锁(君子协定)
对文件进行加写锁之后,还是可以向文件中写入数据内容的,结果说明文件锁是独立于文件的,并没有真正锁定对文件的读写操作,也就是说文件锁只能用于锁定同样遵循"操作前先尝试获取文件锁"的这种操作,如果对方不遵守该协定,则文件锁无法保证线性操作安全
0x11: 文件元数据
1. 获取文件元数据
从i节点中提取文件的元数据,即文件的属性信息
2. 辅助分析文件类型的实用宏(在内部实现也是调用了stat系列函数)
. S_ISREG(): 是否普通文件
. S_ISDIR(): 是否目录
. S_ISSOCK(): 是否本地套接字
. S_ISCHR(): 是否字符设备
. S_ISBLK(): 是否块设备
. S_ISLNK(): 是否符号链接
. S_ISFIFO(): 是否有名管道
代码示例
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> const char* mtos(mode_t m){
static char s[];
if(S_ISDIR(m)){
strcpy(s, "d");
}
else if(S_ISSOCK(m)){
strcpy(s, "s");
}
else if(S_ISCHR(m)){
strcpy(s, "c");
}
else if(S_ISBLK(m)){
strcpy(s, "b");
}
else if(S_ISLNK(m)){
strcpy(s, "l");
}
else if(S_ISFIFO(m)){
strcpy(s, "p");
}
else
strcpy(s, "-"); strcat(s, m & S_IRUSR ? "r" : "-");
strcat (s, m & S_IWUSR ? "w" : "-");
strcat (s, m & S_IXUSR ? "x" : "-");
strcat (s, m & S_IRGRP ? "r" : "-");
strcat (s, m & S_IWGRP ? "w" : "-");
strcat (s, m & S_IXGRP ? "x" : "-");
strcat (s, m & S_IROTH ? "r" : "-");
strcat (s, m & S_IWOTH ? "w" : "-");
strcat (s, m & S_IXOTH ? "x" : "-"); if(m & S_ISUID)
s[] = (s[] == 'x' ? 's' : 'S');
if(m & S_ISGID)
s[] = (s[] == 'x' ? 's' : 'S');
if(m & S_ISVTX)
s[] = (s[] == 'x' ? 't' : 'T'); return s;
} int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
}
struct stat statdata;
fstat(fd, &statdata); printf("%s\n", mtos(statdata.st_mode)); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x12: 访问测试
测试调用进程对指定文件是否拥有足够的访问权限
#include <unistd.h>
int access(const char* pathname, int mode);
pathname: 文件路径
. mode: 访问权限,可取以下值
) R_OK: 可读否
) W_OK: 可写否
) X_OK: 可执行否
) F_OK: 存在否
示例代码
#include <stdio.h>
#include <unistd.h> int main(){
char pathname[] = "a.out";
printf("file%s\n", pathname);
if(- == access(pathname, F_OK)){
printf("not exist\n");
}
else{
if(- == access(pathname, R_OK)){
printf("can't read\n");
}
else{
printf("can read\n");
} if(- == access(pathname, W_OK)){
printf("can't write\n");
}
else{
printf("can write\n");
} if(- == access(pathname, X_OK)){
printf("can't execute\n");
}
else{
printf("can execute\n");
}
} return ;
}
0x13: 权限掩码
设置调用进程的权限掩码,进程的权限掩码会屏蔽掉该进程创建文件时指定的权限,调用unask函数可以认为改变调用进程的权限掩码,如果改为0000,则不屏蔽任何权限
#include <sys/stat.h>
mode_t umask(mode_t cmask);
. cmask: 新权限掩码
注意,权限掩码是进程的属性之一,umask函数所影响的仅仅是调用该函数的进程创建新文件,对其父进程,比如shell进程,没有任何影响
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> void printm(mode_t m){
static char s[];
memset(s, , );
strcat(s, m & S_IRUSR ? "r" : "-");
strcat(s, m & S_IWUSR ? "w" : "-");
strcat(s, m & S_IXUSR ? "x" : "-");
strcat(s, m & S_IRGRP ? "r" : "-");
strcat(s, m & S_IWGRP ? "w" : "-");
strcat(s, m & S_IXGRP ? "x" : "-");
strcat(s, m & S_IROTH ? "r" : "-");
strcat(s, m & S_IWOTH ? "w" : "-");
strcat(s, m & S_IXOTH ? "x" : "-"); printf("%s\n", s);
} int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} struct stat statdata;
fstat(fd, &statdata);
printf("before chmod: \n");
printm(statdata.st_mode); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} umask(); fd = open("data1.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
}
printf("after chmod\n");
fstat(fd, &statdata);
printm(statdata.st_mode); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x14: 内存映射文件
内存映射文件不仅提供了一种以访问内存的方式读写文件的方法,而且还在多个进程之间打通了一条基于文件共享的数据通道
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> int main(){
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} ftruncate(fd, );
char* p = (char*)mmap(NULL, , PROT_READ | PROT_WRITE, MAP_SHARED, fd, );
if(p == MAP_FAILED){
perror("mmap");
exit(EXIT_FAILURE);
} strcpy(p, "Hello, File!");
printf("%s\n", p); if(munmap(p, ) == -){
perror("munmap");
exit(EXIT_FAILURE);
} strcpy(p+=, "Hello, File Again!");
printf("%s\n", p); if(munmap(p, ) == -){
perror("munmap");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x15: 硬链接
硬链接的本质就是目录文件里一个文件名和i节点号的对应条目。通过该条目,就可以根据一个文件的文件名迅速地找到与之相对应的i节点号,进而访问该文件的数据
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> int main(){
int fd = open("foo,txt", O_RDWR | O_CREAT, );
if(- == fd){
perror("open");
exit(EXIT_FAILURE);
} int linkresult = link("foo.txt", "bar.txt");
if(- == linkresult){
perror("link");
exit(EXIT_FAILURE);
} unlink("foo.txt");
rename("bar.txt", "newbar.txt"); char text[] = "the content that be writen into foo.txt";
size_t towrite = strlen(text);
ssize_t written = write(fd, text, towrite);
if(- == written){
perror("write");
exit(EXIT_FAILURE);
} if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} fd = open("newbar.txt", O_RDONLY, );
if(- == fd){
perror("newbar.txt open");
exit(EXIT_FAILURE);
} char text1[] = {};
size_t toread = ;
ssize_t readed = read(fd, text1, toread);
if(- == readed){
perror("read");
exit(EXIT_FAILURE);
}
printf("%s\n", text1); if(- == close(fd)){
perror("close");
exit(EXIT_FAILURE);
} return ;
}
0x16: 目录的创建与删除
在进程中使用mkdir函数创建一个空目录,使用函数rmdir删除一个空目录
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h> int main(){
mkdir("newpath", );
getchar();
rmdir("newpath"); return ;
}
0x17: 当前工作目录
当前工作目录是每个进程的属性之一,保存在进程表中,它是系统内核为进程解析相对路径的起点
#include <stdio.h>
#include <unistd.h>
int main()
{
char buf[] = {};
getcwd(buf, );
printf("%s\n", buf);
chdir("/home/tarena/unixc/day01");
getcwd(buf, );
printf("%s\n", buf);
return ;
}
0x18: 获取目录内容
目录由若干条目组成,每个条目均包含文件名、文件类型、i节点号等信息。readdir函数可以连续调用,调用一次返回一个条目,再调用一次返回下一个条目,直到返回NULL表示已经读完整个目录或者发生错误,为了区分这两种情况,可以通过检查errno是否被重置来进行判断
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h> bool printpathname(DIR* dirp){
errno = ;
struct dirent* direntp;
direntp = readdir(dirp);
if(!direntp){
if(!errno){
return true;
}
perror("readdir");
exit(EXIT_FAILURE);
}
printf("%s\n", direntp->d_name); return false;
} int main(){
int i;
DIR* dirp = opendir("/root/tarena/");
if(!dirp){
perror("opendir");
exit(EXIT_FAILURE);
} int offset;
for(i = ; ;i++){
if(printpathname(dirp))
break;
if(i == )
offset = telldir(dirp);
} seekdir(dirp, offset);
printpathname(dirp); rewinddir(dirp);
for(i = ; ;i++){
if(printpathname(dirp))
break;
}
closedir(dirp); return ;
}
出于线程安全的原因,新的Linux版本将全局变量改成了局部变量。最直观的解决办法就是在程序开头加上#include <errno.h>,将extern int errno这一句省略
12. 进程管理
0x1: 父子进程共享文件表
fork函数成功返回以后,系统内核为父进程维护的文件描述符表也被复制到子进程的进程表项中,文件表项并不复制
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#define BUFSIZE 1024 * 1024
bool lock(int fd)
{
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = ;
lock.l_len = ;
lock.l_pid = -;
if (fcntl (fd, F_SETLK, &lock) == -)
{
if (errno != EAGAIN)
{
perror ("fcntl");
exit (EXIT_FAILURE);
}
returnfalse;
}
returntrue;
}
void unlock(int fd)
{
struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = ;
lock.l_len = ;
lock.l_pid = -;
if (fcntl (fd, F_SETLKW, &lock) == -)
{
perror ("fcntl");
exit (EXIT_FAILURE);
}
}
void writedata(int fd, char *buf, char c)
{
while(!lock(fd));
for (int i = ; i < BUFSIZE - ; i++)
buf[i] = c;
for (int i = ; i <; i++)
{
int writed;
if ((writed = write (fd, buf + i, )) == -)
{
perror ("write");
exit (EXIT_FAILURE);
}
printf("111111111->%c,buf[0]=%c, writed = %d\n", c, *(buf + i), writed);
}
unlock(fd);
}
int main()
{
int fd = open ("data.txt", O_RDWR | O_CREAT | O_TRUNC, );
if (fd == -)
{
perror ("open");
exit (EXIT_FAILURE);
}
pid_t pid;
if ((pid = fork()) <)
{
perror("fork");
return1;
}
if (pid == )
{
char buf[BUFSIZE] = {};
writedata(fd, buf, '');
}
else
{
char buf[BUFSIZE] = {};
writedata(fd, buf, '');
}
if (close (fd) == -)
{
perror ("close");
exit (EXIT_FAILURE);
}
return0;
}
0x2: 孤儿与僵尸
父进程创建子进程以后,子进程在操作系统的调度下与其父进程同时运行。如果父进程先于子进程终止,子进程即成为孤儿进程,同时被init进程收养,即成为init进程的子进程,因此init进程又被称为孤儿院进程。一个进程成为孤儿进程是正常的,系统中的很多守护进程都是孤儿进程。
如果子进程先于父进程终止,但父进程由于某种原因,没有回收子进程的退出状态,子进程即成为僵尸进程。僵尸进程虽然已经不再活动,但其终止状态仍然保留,也会占用系统资源,直到被其父进程回收才得以释放。如果父进程直到终止都未回收它的已成僵尸的子进程,init进程会立即收养并回收这些处于僵尸状态的子进程,因此一个进程不可能既是孤儿进程同时又是僵尸进程。一个进程成为僵尸进程需要引起注意,如果它的父进程长期运行而不终止,僵尸进程所占用的资源将长期得不到释放
aaarticlea/png;base64,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" alt="" />
Copyright (c) 2016 LittleHann All rights reserved
C/C++ Learning的更多相关文章
- 【Machine Learning】KNN算法虹膜图片识别
K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- 【Machine Learning】Python开发工具:Anaconda+Sublime
Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...
- 【Machine Learning】机器学习及其基础概念简介
机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- 【Machine Learning】决策树案例:基于python的商品购买能力预测系统
决策树在商品购买能力预测案例中的算法实现 作者:白宁超 2016年12月24日22:05:42 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本 ...
- Deep learning:五十一(CNN的反向求导及练习)
前言: CNN作为DL中最成功的模型之一,有必要对其更进一步研究它.虽然在前面的博文Stacked CNN简单介绍中有大概介绍过CNN的使用,不过那是有个前提的:CNN中的参数必须已提前学习好.而本文 ...
- Programming Learning - Based on Project
Today when taking a bath I got a good idea that it is an efficient and interesting way to learn a ne ...
- 做中学(Learning by Doing)之背单词-扇贝网推荐
做中学(Learning by Doing)之背单词-扇贝网推荐 看完杨贵福老师(博客,知乎专栏,豆瓣)的「继续背单词,8个月过去了」,我就有写这篇文章的冲动了,杨老师说: 有时候我会感觉非常后悔,如 ...
- 【原】Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令
<Learning Spark>这本书算是Spark入门的必读书了,中文版是<Spark快速大数据分析>,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足 ...
- 【原】Learning Spark (Python版) 学习笔记(四)----Spark Sreaming与MLlib机器学习
本来这篇是准备5.15更的,但是上周一直在忙签证和工作的事,没时间就推迟了,现在终于有时间来写写Learning Spark最后一部分内容了. 第10-11 章主要讲的是Spark Streaming ...
- 【机器学习Machine Learning】资料大全
昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...
随机推荐
- ReactNative真机运行运行
注意在iOS设备上运行React Native应用需要一个Apple Developer account并且把你的设备注册为测试设备.本向导只包含React Native相关的主题. 译注:从XCod ...
- 《细细品味Hive》系列课程
Hi,博友: 我是解耀伟,笔名是虾皮,最近我在极客学院录制Hive系列教程,也是督促自己学习一种方式,可以把自己的学习积累有方向,星期天也能做点有意义的事情.在做每一期的过程中,需要找资料,总结,先自 ...
- 从大公司做.NET 开发跳槽后来到小公司的做.NET移动端微信开发的个人感慨
从14年11月的实习到正式的工作的工作我在上一家公司工作一年多了.然而到16年5月20跳槽后自己已经好久都没有在写博客了,在加上回学校毕业答辩3天以及拿档案中途耽搁了几天的时间,跳槽后虽然每天都在不停 ...
- 自定义圆形控件RoundImageView并认识一下attr.xml
今天我们来讲一下有关自定义控件的问题,今天讲的这篇是从布局自定义开始的,难度不大,一看就明白,估计有的同学或者开发者看了说,这种方式多此一举,但是小编我不这么认为,多一种解决方式,就多一种举一反三的学 ...
- node简单操作mysql的类
Creative.js 'use strict'; var pool = require('../utils/MysqlUtils'); var util = require('util'); var ...
- [BZOJ1143][CTSC2008]祭祀river(最长反链)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1143 分析: 最长反链==最小路径覆盖==n-二分图最大匹配数 某神犇对二分图的总结: ...
- Excel——将内容导入
1.写入Excel文件的操作引入Microsoft.Office.Tools.Excel.dll 程序集 List<Person> list = new List<Person> ...
- iOS--更新cooped库
- eclipse汉化
一.准备工作: 1.eclipse点击help——about eclipse查看软件版本,如图: 2.登录官网语言包下载地址:http://www.eclipse.org/babel/download ...
- 树分治 点分治poj 2114
存在2点间距离==k 输出AYE 否则输出NAY #include<stdio.h> #include<string.h> #include<algorithm> ...