12.内存分区说明

1.程序编译过程

编译过程又可以分成两个阶段:编译和汇编。

编译:

编译是读取源程序(字符流),对之进行语法分析,将高级语言指令转换为功能等效的汇编代码,

编译过程包括两个主要阶段:编译预处理和编译、优化

编译预处理:

(1).宏定义指令替换(宏定义展开)

(2).条件编译指令,

(3).头文件包含指令(头文件展开);注释不被处理

编译、优化阶段:

经过预编译得到的输出文件中,只有常量;如数字、字符串、变量的定义

汇编:

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。 

(1).text(代码区):只读,函数,包含了操作系统和应用程序的所有代码;

(2).data区(数据区):初始化的数据,全局变量,static变量,文字常量(只读);

(3).bss区(bss段):没有初始化的数据,全局变量,static变量;

(4).stack(栈区):普通局部变量,自动管理内存,先进后出;

(5).heap(堆区):手动申请空间,整个程序结束,系统也会自动回收。

2.栈越界

函数递归,容易导致栈越界,出现段错误

3.memset()

void *memset(void *s,int c,size_t n);

清空内存,填充字符;

4.memcopy()

void *memcopy(void *s, int c,size_t n);

n拷贝内存的总大小;使用memcopy()要考虑内存重叠,最好使用memmove();

5.memcmp()

int memcmp(const void *buf1, const void *buf2, unsigned int count);

比较两个数据是否相等,大小;

比较内存区域buf1和buf2的前count个字节。

6.堆区内存分配与释放

int *p;
*p = 10;
printf("*p = %d\n", *p);     //野指针,出现段错误

解决:

a.在栈区申请一个空间,指针指向这个空间;

b.在堆区申请一个空间(malloc(),头文件:#include<stdlib.h>),指针指向这个空间;

7.malloc()

a.参数是指定的堆区分配多大的空间;

b.返回值:成功就是堆区空间的首元素地址;

c.失败返回NULL;

int *p;
p = (int *)malloc(sizeof(int));

d.使用free()释放,不是释放变量,而是释放p所指向的内存,释放是指系统回收了,如果再用就是非法操作内存

8.内存泄漏

动态分配空间,不释放。

9.内存污染

操作野指针所指向的内存,堆栈越界。

10.指针指向内存空间释放

 只能释放一次,每次释放前先判断是否为空:

11.返回栈区地址

操作非法内存,段错误;

fun()的变量存储在栈区,调用完就释放了,后面再操作就是非法操作;

 12.值传递

正常,p只是作为形参

 

posted @ 2019-01-01 16:45  西贡小傻  Views(172)  Comments(0Edit  收藏  举报