C语言常见内存错误

C语言指针和内存泄露

常见的内存错误:

1.      内存分配未成功却使用了它。

如果指针p是函数的参数,要在函数的入口处用assert(p!=NULL)进行检查;

如果是用malloc来动态申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理。

2.      内存分配成功,尚未初始化就使用它。

3.      内存分配成功并且初始化,但操作越界。

例如在使用数组时经常发生“多1”或“少1”操作。

4.      忘记释放内存造成内存泄露。

一般我们常说的内存泄露是指堆内存的泄露。堆内存是指程序从堆中动态分配的使用完成后必须显式释放的内存。应用程序一般使用malloc,calloc,realloc等从堆中分配到一块内存,使用完后,需调用free释放该内存块,否则这块内存就不能被再次调用,这块内存就内泄露了。

导致内存泄露的场景:

1.      重新赋值

char*memoryArea = malloc(10);

char*newArea = malloc(10);

memoryArea 和 newArea 分别被分配了 10 个字节,如图下图所示。如果执行如下所示的语句(指针重新赋值)

memoryArea= newArea;

在上面的代码语句中,开发人员将 memoryArea 指针赋值给 newArea 指针。结果,memoryArea 以前所指向的内存位置变成了孤立的,如下面的图所示。它无法释放,因为没有指向该位置的引用。这会导致 10 个字节的内存泄漏。

在对指针赋值前,请确保内存位置不会变为孤立的。

2.首先释放父块

假设有一个指针 memoryArea,它指向一个 10 字节的内存位置。该内存位置的第三个字节又指向某个动态分配的 10 字节的内存位置。

free(memoryArea)

如果通过调用 free 来释放了 memoryArea,则 newArea 指针也会因此而变得无效。newArea 以前所指向的内存位置无法释放,因为已经没有指向该位置的指针。换句话说,newArea 所指向的内存位置变为了孤立的,从而导致了内存泄漏。

每当释放结构化的元素,而该元素又包含指向动态分配的内存位置的指针时,应首先遍历子内存位置(在此例中为 newArea),并从那里开始释放,然后再遍历回父节点。

这里的正确实现应该为:

free(memoryArea->newArea);

free(memoryArea);

3.返回值的不正确处理

有时,某些函数会返回对动态分配的内存的引用

char*func ( )

{

return malloc(20);

}

voidcallingFunc ( )

{

func ( );

}

在上面的示例中,callingFunc() 函数中对 func() 函数的调用未处理该内存位置的返回地址。结果,func() 函数所分配的 20 个字节的块就丢失了,并导致了内存泄漏。

时间: 2024-12-23 07:11:14

C语言常见内存错误的相关文章

大内高手—常见内存错误

转自:http://blog.chinaunix.net/uid-23228758-id-4355524.html 随着诸如代码重构和单元测试等方法引入实践,调试技能渐渐弱化了,甚至有人主张废除调试器.这是有道理的,原因在于调试的代价往往太大了,特别是调试系统集成之后的BUG,一个BUG花了几天甚至数周时间并非罕见. 而这些难以定位的BUG基本上可以归为两类:内存错误和并发问题.而又以内存错误最为普遍,即使是久经沙场的老手,也有时也难免落入陷阱.前事不忘,后世之师,了解这些常见的错误,在编程时就

常见内存错误的几点总结

学习C语言以来一直没有注意到细节的控制,敲代码总是"无所顾忌"的.如今慢慢把程序写大写复杂了.在资源宝贵和的嵌入式中.这个问题越来越须要注意了--内存的管理..让编程慢慢走上正轨,慢慢走上可预见性吧,慢慢与机器融为一体,慢慢习惯于如梁肇新前辈所说以机器的思维方式思维吧!!! 1.返回局部变量地址将引起内存错误 2.暂时空间过大:操作系统在载入某个应用程序时,都将为其分配一定大小的栈空间,若申请过大的局部变量.可能会引起栈溢出问题. (PC机上Windows和Linux系统一般不必操心这

[草稿][C语言][内存分配]常见内存错误

1. 使用未分配成功的内存 解决案: ①在使用内存前检查指针是否为NULL ②参数是指针时,在函数入口处用assert进行判断 ③如果指针指向动态申请的内存,用if进行容错处理 2. 使用分配成功,但未初始化的内存 解决案: ①定义数组后一定要初始化 3. 内存泄漏 解决案: ①new/malloc和delete/free一定要成对出现 4. 使用已被释放的内存 解决按: ①不要返回指向栈内存的指针或引用 ②释放内存后,将指针置为NULL

C语言中常见的内存错误与解决方法

常见的错误 关于内存的一些知识已在内存分配中提及,现记录与分享常见的内存错误与对策. 类型 1:内存未分配成功,却使用了它. 方   法:在使用之前检查指针是否为NULL. 1)当指针p是函数的参数时,在函数入口处用语句assert(p!=NULL)进行断言检查. 2)当使用malloc或new来申请内存时,应该用if(p != NULL)进行防错检查. 类型 2:引用了尚未初始化的指针 原   因:内存的缺省初始值究竟是什么并没有统一的标准,在使用之前都进行初始化. 1)没有初始化的观念. 2

C语言常见错误中英文对照表

fatal error C1003:  error count exceeds number; stopping compilation 中文对照:错误太多,停止编译 分析:修改之前的错误,再次编译 fatal  error  C1004: unexpected end of file found 中文对照:文件未结束  分析:一个函数或者一个结构定义缺少“}”.或者在一个函数调用或表达式中括号没有配对出现.或者注释符“/*…*/”不完整等 fatal  error C1083:  Cannot

常见动态内存错误---内存泄漏

常见动态内存错误 编译器不能自动发现动态内存错误,动态内存错误通常只能在程序运行时才能被捕捉到,而且错误原因不容易查找,错误本身也不容易捕捉,改错难度较大. 1.动态内存分配失败却继续操作 内存不足等有可能导致动态内存分配失败,所以使用new请求分配动态内存后一定要检查返回地址是否为NULL. 如用if(p==NULL) 或 if(p!=NULL)进行检查,未检查前不要操作动态内存空间. 2.动态内存空间未初始化就进行读操作 C++标准并未规定动态内存空间的默认值,程序无法预知该默认值的具体指.

PHP编程中10个最常见的错误

PHP是一种非常流行的开源服务器端脚本语言,你在万维网看到的大多数网站都是使用php开发的.本篇经将为大家介绍PHP开发中10个最常见的问题,希望能够对朋友有所帮助. 错误1:foreach循环后留下悬挂指针 在foreach循环中,如果我们需要更改迭代的元素或是为了提高效率,运用引用是一个好办法: 1 2 3 4 5 $arr = array(1, 2, 3, 4); foreach ($arr as &$value) {     $value = $value * 2; } // $arr

Java千百问_04异常处理(008)_java中常见的错误有哪些

点击进入_更多_Java千百问 java中常见的错误有哪些 想了解异常看这里:什么是java中的异常 常见的运行时异常看这里:常见的Java异常有哪些(运行时) 常见的非运行时异常看这里:常见的java异常有哪些(非运行时) java中除了异常Exception之外,还有一大类错误,即ERROR,我们常见的ERROR如下: 1.java.lang.Error 错误.是所有错误的基类,用于标识严重的程序运行问题.这些问题通常描述一些不应被应用程序捕获的反常情况. 原因: 对系统所访问外部资源,未执

C++语言学习(十二)——C++语言常见函数调用约定

C++语言学习(十二)--C++语言常见函数调用约定 一.C++语言函数调用约定简介 C /C++开发中,程序编译没有问题,但链接的时候报告函数不存在,或程序编译和链接都没有错误,但只要调用库中的函数就会出现堆栈异常等现象.上述现象出现在C和C++的代码混合使用的情况下或在C++程序中使用第三方库(非C++语言开发)的情况下,原因是函数调用约定(Calling Convention)和函数名修饰(Decorated Name)规则导致的.函数调用约定决定函数参数入栈的顺序,以及由调用者函数还是被