C/C++中内存泄漏常有例子
1、什么是内存泄漏?
在定义一个指针的时候,需要给他分配一段内存空间,防止他变为野指针,而这个指针在分配一段内存地址的时候没有释放,等下次再次使用这个指针再次为他分配内存空间,再使用,未释放,如此一来内存空间不断在消耗,这种现象叫内存泄漏。
2、发生内存泄漏的例子。
2.1、丢失内存分配的地址,导致无法释放
int main()
{char *p;p = (char *)malloc(100);p = "hello world"; // p指向其他地方,把字符串的首地址赋给p;这样子导致原本堆区的空间找不到了//从此刻起,再也找不到申请的100个字节的空间,动态申请的100个字节被泄漏了return 0;
}
2.2、封装的函数申请了堆空间未释放,每调用一次泄漏一次
void test1()
{char *p;p =(char *)malloc(100); //接下来,可以用p指向内存了 , //...//没有释放,没有返回,这样导致这个函数执行完后不知道这个申请的内存空间在哪了
}void main()
{//每次用一次fun泄露100个字节 test1();test1();
}
2.3、错误处理流程中的return导致的内存泄漏
bool MyFunction() { MyClass* obj = new MyClass(); // ... 一些操作 ... if (/* 某个错误条件 */) { return false; // 忘记删除obj,导致内存泄漏 } delete obj; // 如果没有return,这里会释放内存 return true;
}
2.4、异常改变了程序的正常流程导致的内存泄漏
void MyFunction() { MyClass* obj = new MyClass(); try { // ... 一些可能抛出异常的代码 ... } catch (...) { // 异常处理,但忘记了删除obj throw; // 重新抛出异常,obj指向的内存未释放 } // 如果没有异常,这里会释放内存 delete obj;
}
2.5、使用第三方库时忘记释放资源:
void MyFunction() { SomeLibraryHandle handle = SomeLibrary_AllocateResource(); // 使用资源... // 忘记调用SomeLibrary_FreeResource(handle)来释放资源
}
2.6、全局/静态变量引起的内存泄漏
//全局或静态变量在程序的生命周期内都存在,如果它们指向动态分配的内存,并且这些内存没有在程序结束前被释放,那么就会发生内存泄漏。
MyClass* globalObj = new MyClass(); // 全局变量指向动态分配的内存
// ... 程序的其他部分 ...
// 程序结束,但globalObj指向的内存没有被释放
2.7、循环或递归中不恰当的内存管理
//在循环或递归中分配内存,但忘记在每次迭代或递归调用后释放它,也会导致内存泄漏。
void LeakyFunction() { for (int i = 0; i < 1000; ++i) { MyClass* obj = new MyClass(); // 不断分配新内存 // ... 使用obj ... // 忘记删除obj } // 循环结束后,大量内存未释放
}
2.8、使用智能指针不当或忘记使用
智能指针(如std::unique_ptr和std::shared_ptr)可以帮助管理动态分配的内存,但如果使用不当或忘记使用,仍可能导致内存泄漏。
为了避免内存泄漏,应该遵循一些基本原则:始终在适当的时候释放动态分配的内存,使用智能指针来管理动态内存分配,仔细处理异常和错误情况,以及在循环或递归中正确管理内存。同时,使用内存检测工具(如Valgrind)可以帮助发现和定位内存泄漏问题。