Advertisement

《C语言深度解刨》阅读笔记 Ⅴ

阅读量:

第五章、内存管理

为了避免出现野指针现象,在内存管理中对指针进行初始化操作,并确保在使用后将其设为NULL。
栈、队和静态区
静态区域的作用是存储自动全局变量以及带有static关键字的局部变量(包括全局 static 和局部 static 类型的变量)。该区域内的信息在整个程序运行期间始终保持存在状态。
栈的主要作用是临时存储函数级别的局部变量。栈上的数据仅限于当前函数执行期间的有效范围。
动态内存分配空间通常通过malloc、free或new等关键字来实现管理。这些空间块的存在会受到free或delete指令的影响

  • 指针没有指向一篇合法内存的常见错误:
    ①结构体成员指针未初始化;
    ②没有为结构体指针分配足够的内存空间;
    ③函数的入口检验(不管什么时候,我们使用指针之前一定要确保指针是有效的。)
    一般在函数入口处使用assert(NULL != p)对参数进行校验。在非参数的地方使用
    if(NULL != p)来校验。但这都有一个要求,即p 在定义的同时被初始化为NULL 了。

assert不是一个函数而是通过头文件assert.h定义的一个宏。当该宏在其后括号内的表达式评估为false时(即表达式结果为0或非真),程序将立即停止执行并显示错误信息;若该表达式的值为true,则会继续执行后续的代码块。需要注意的是,在编译器配置为释放模式时(通常表示优化级别更高),该宏会被编译器完全移除以消除潜在的安全漏洞风险,并且不会对程序的整体性能产生任何负面影响。

作为调试代码的辅助工具,assert 宏的主要功能就是最大限度减少函数调用时可能出现的错误。
它可以帮助开发者快速定位到代码中潜在的问题所在。
值得注意的是,
函数本身并无问题,
而是调用者传过来的实参出现了问题。
通过 assert 宏,
我们可以更好地理解程序运行过程中的各种异常情况。

当为指针分配的内存不足时——可能导致越界行为。例如,在字符串拷贝操作中若未正确添加结束标志符‘/0’会导致拷贝后的数据出现错误。解决办法是加上这个字符串结束标志符:char *p2 = (char *)malloc(sizeof(char)strlen(p1)+1sizeof(char));

  • 内存泄漏
    会产生内存泄漏现象的就是那些位于堆区的内存块。这里仅考虑通过malloc系列函数或者new操作符所导致的具体分配方式下的内存泄漏问题。一旦这些预先分配好的存储空间未被及时释放或者删除,则会导致相应的静态分配区域无法被释放而存活到程序结束。

  • malloc函数的原型定义如下:(void*)malloc(int size);

  • 要使用malloc函数需要满足以下条件:

    • 内存被分配给谁?
    • 如何确定要分配多少内存?
    • 是否还存在足够的内存空间可供分配?
    • 该内存块将用于存储何种类型的数据显示?
    • 最终生成的内存块位于何处?
  • 使用malloc后,并应确保调用完成后if(NULL!=p)判断能正确返回。

  • malloc函数允许申请大小为零的内存块;然而该函数并不会返回NULL值而给出一个合法的内存地址。但即使如此,在实际应用中仍需注意:如果内存块大小确实是零,则无法对其进行操作,并且相应的校验条件无法生效。

  • 一旦进行过内存分配操作,则必须执行相应的释放操作以避免资源泄漏。

调用free函数后,p所指向的内存块已被释放;必须将p重新置零。

全部评论 (0)

还没有任何评论哟~