C语言内存分配问题(整理)

上传人:油条 文档编号:24911978 上传时间:2017-12-08 格式:PDF 页数:4 大小:196.25KB
返回 下载 相关 举报
C语言内存分配问题(整理)_第1页
第1页 / 共4页
C语言内存分配问题(整理)_第2页
第2页 / 共4页
C语言内存分配问题(整理)_第3页
第3页 / 共4页
C语言内存分配问题(整理)_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《C语言内存分配问题(整理)》由会员分享,可在线阅读,更多相关《C语言内存分配问题(整理)(4页珍藏版)》请在金锄头文库上搜索。

1、1、 C 中内存分为四个区 栈:用来存放函数的形参和函数内的局部变量。 由编译器分配空间,在函数执行完后由编译器自动释放。 堆:用来存放由动态分配函数(如 malloc)分配的空间。 是由程序员自己手动分配的,并且必须由程序员使用 free 释放。如果忘记用 free 释放,会导致所分配的空间一直占着不放,导致内存泄露。 堆,顺序随意。栈,后进先出 (Last-In/First-Out)。 全局区(静态区):用来存放全局变量和静态变量。 存在于程序的整个运行期间,是由编译器分配和释放的。 文字常量区: 例如 char *c = “123456”;则 ”123456”为文字常量,存放于文字常量区

2、。也由编译器控制分配和释放。 程序代码区:用来存放程序的二进制代码。 我查了下资料,有说分四个,有说分五个加一个程序代码区,我没查到参考的专业书籍。所以麻烦知道的告知一下,完善一下。 2、 内存分配方式 内存分配方式有三种: 1) 从静态存储区域分配。 内存 在程序编译的时候就已经分配好, 这块内存在程序的整个运行期间都存在。例如全局变量, static 变量。 2) 在栈上创建。 在执行函数时, 函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。 栈内存分配运算内置于处理器的指令集中, 效率很高,但是分配的内存容量有限。 3) 从堆上分配,亦称动态内存分配。 程

3、序在运行的时候 用 malloc 或 new 申请任意多少的内存 ,程序员自己负责在何时 用 free 或 delete 释放内存 。 动态内存的生存期由我们决定,使用非常灵活,但问题也最多。 3、 常见的内存错误及其对策 发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。 而这些错误大多没有明 显的症状,时隐时现,增加了改错的难度。 有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。常见的内存错误及其对策如下: 1) 内存分配未成功,却使用了它。 编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。 常用解决办法是,在使用

4、内存之前检查指针是否为 NULL。 如果指针 p 是函数的参数, 那么在函数的入口处用assert(p!=NULL)进行检查。如果是用 malloc 或 new 来申请内存,应该用 if(p=NULL) 或if(p!=NULL)进行防错处理。 2)内存分配虽然成功,但是尚 未初始化就引用它。 犯这种错误主要有两个起因: 一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。 内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。 所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。 3)内存分配成功并且

5、已经初始化,但操作越过了内存的边界。 例如 在使用数组时经常发生下标 “多 1”或者 “少 1”的操作 。特别是在 for 循环语句中,循环次数很容易搞错,导致数组操作越界。 4)忘记了释放内存,造成内存泄露。 含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽 。动态内存的申请与释放必须配对,程序中 malloc 与 free 的使用次数一定要相同,否则肯定有错误( new/delete 同理)。 【规则 1】用 malloc 或 new 申请内存之后,应该立即检查指针值是否为 NULL。防止使用指针值为 NULL

6、 的内存。 【规则 2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。 【规则 3】 注意不要返 回指向 “栈内存 ”的 “指针 ”或者 “引用 ”,因为该内存在函数体结束时被自动销毁。 【规则 4】避免数组或指针的下标越界,特别要当心发生 “多 1”或者 “少 1”操作。 【规则 5】动态内存的申请与释放必须配对,防止内存泄漏。 【规则 6】用 free 或 delete 释放了内存之后,立即将指针设置为 NULL,防止产生 “野指针 ”。 4、 动态分配释放内存举 例 用 malloc 动态分配内存后一定要 判断一下分配是否成功,判断指针的值是否为 NULL。 内存分

7、配成功后要对内存单元进行初始化。 内存分配成功且初始化后 使用时别越界了。 内存使用完后要用 free( p)释放, 注意,释放后, p 的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。为了防止后面继续使用这块内存,应在 free(p)后,立即 p=NULL,这样后面如果要使用,判断 p 是否为 NULL 时就会判断出来。 NO.1 void GetMemory(char *p) p = (char *)malloc(100); void Test(void) char *str = NULL; GetMemory(str); strcpy(str,hell

8、o world); printf(str); 请问运行 Test 函数后会是什么样的结果? NO.2 char *GetMemory(void) char p = hello world; retrun p; void Test(void) char *str = NULL; str = GetMemory(); printf(str); 问题同 NO.1 NO.3 void GetMemory(char *p, int num) *p = (char *)malloc(num); void Test(void) char *str = NULL; GetMemory( strcpy(str,

9、hello); printf(str); 问题同 NO.1 NO.4 void Test(void) char *str = (char *)malloc(100); strcpy(str,hello); free(str); if(str != NULL) strcpy(str,world); printf(str); 问题同 NO.1 我对以上问题的分析: NO.1: 程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL(即 str 里存的是 NULL的地址, *str 为 NULL 中的值为), 调用函数的过程中做了如下动作: 1、申请一个 char 类型的指针

10、p, 2、把 str 的内容 copy 到了 p 里(这是参数传递过程中系统所做的) , 3、为 p 指针申请了 100 个空间, 4、返回 Test 函数最后程序把字符串 hello world 拷贝到 str 指向的内存空间里 到这里错误出现了! str 的空间始终为 NULL 而并没有实际的空间深刻理解函数调用的第 2 步 ,将不难发现问题所在! (注意:传递的参数和消除的参数) NO.2: 程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL调用函数的过程中做了如下动作: 申请一数组 p并将其赋值为 hello world(数组的空间大小为 12), 返回数组名

11、 p 付给 str 指针(即返回了数组的首地址) 那么这样就可以打印出字符串 hello world了么?当然是不能的! 因为在函数调用的时候漏掉了最后一步 也就是在第步 return 数组名后,函数调用还要进行一步操作,也就是释放内存空间 当一个函数被调用结束后它会 释放掉它里面所有的变量所占用的空间 所以数组空间被释放掉了 ,也就是说 str 所指向的内容将不确定是什么东西 NO.3: 正确答案为可以打印出 hello 但内存泄漏了! 需要用 free()函数进行释放 。 NO.4: 申请空间,拷贝字符串,释放空间前三步操作都没有任何问题 到 if 语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是 NULL,而是一个不确定的值 所以 if 语句永远都不能被 正确 执行这也是著名的野指针问题 所以我们在编写程序释放一个指针之后一定要人为的将指针付成 NULL 这样就会避免出现野指针的出现有人说野指针很可怕,会带来意想不到的错误 参考文章 1: http:/ 2: http:/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号