问题三十八:C++中bad alloc问题(1)——分析问题
来源:互联网 发布:c语言写图书管理系统 编辑:程序博客网 时间:2024/06/05 04:06
38.1 针对问题,解决问题
内存泄漏问题在小程序中很难被发现,只有在内存用完后,导致分配内存出现“bad alloc”时才能被发现。
如下是在“画六个圆环”时出现的“bad alloc”问题。(圆环的每个像素点都需要解一个一元四次方程,可能是在调用解方程函数时动态分配了太多的内存,然后忘了释放,然后内存全被用完了)
原因肯定是:动态分配的内存没有释放,导致内存泄漏。(new 和delete没有配合好。)
我们以调用“一元二次方程”函数为例,进行说明。
float* roots_quadratic_equation(float a, float b, float c) {
//the first element is thenumber of the real roots, and other elements are the real roots.
float *roots = new float[3];
/*为了使函数返回一个数组,将roots指针指向动态分配的数组空间的首地址,然后return roots将数组空间的首地址返回*/
if (a == 0.0) {
if (b == 0.0) {
roots[0] = 0.0;
}
else {
roots[1] = -c/b;
roots[0] = 1.0;
}
}
else {
float d = b*b - 4*a*c;
if (d < 0.0) {
roots[0] = 0.0;
}
else {
roots[1] = (-b +sqrt(d)) / (2*a);
roots[2] = (-b -sqrt(d)) / (2*a);
roots[0] = 2.0;
}
}
return roots;
}
int main(){
float *r= new float[3];
/*将r指针指向动态分配的数组空间的首地址*/
r =roots_quadratic_equation(1.0, -3.0, 2.0);
/*将roots_quadratic_equation()函数返回的指向动态分配的数组空间的首地址赋值给指针r,也就是使r指向在roots_quadratic_equation()动态分配的数组空间的首地址*/
for (int i=0;i<(r[0]+1); i++) {
std::cout <<"r[" << i << "]=" << r[i] << endl;
}
}
如上main()函数对roots_quadratic_equation()的调用存在两个问题:
其一,将r指向在roots_quadratic_equation()动态分配的数组空间的首地址后,在使用完后,需要delete [] r:
int main(){
float *r= new float[3];
r =roots_quadratic_equation(1.0, -3.0, 2.0);
for (int i=0;i<(r[0]+1); i++) {
std::cout <<"r[" << i << "]=" << r[i] << endl;
}
delete[] r;
}
因为r指向在roots_quadratic_equation()动态分配的数组空间的首地址,所以delete [] r释放的是:roots_quadratic_equation()动态分配的数组空间
这个确实可以有效地“减轻”问题。
作此修改后,运行结果:
报错时间晚了,但是还是“bad_alloc”
问题在哪?
其二,在main()函数中,声明指针时,没有必要指向一个动态分配的数组空间的首地址。否则,由于r在后面被重新赋值,所以main()函数中多余的动态分配的数组空间成了“僵尸空间”(无法寻址,无法释放)
int main(){
float *r;
r =roots_quadratic_equation(1.0, -3.0, 2.0);
for (int i=0;i<(r[0]+1); i++) {
std::cout <<"r[" << i << "]=" << r[i] << endl;
}
delete [] r;
}
修改完后的运行结果:
综述,对于调用“返回函数内部动态分配的空间地址”的函数:
float *r;
r =roots_quadratic_equation(1.0, -3.0, 2.0);
for (int i=0;i<(r[0]+1); i++) {
std::cout <<"r[" << i << "]=" << r[i] << endl;
}
delete[] r;
- 问题三十八:C++中bad alloc问题(1)——分析问题
- 问题三十八:C++中bad alloc问题(2)——使用“引用”避免该问题
- Object c中的alloc和init问题
- Object c中的alloc和init问题
- vtk实战(三十八)——读取jpg数据(有问题)
- alloc init问题
- 了解alloc、init的问题1
- ActivityGroup window bad token问题深入分析
- OC中alloc内存分配大小的问题
- bad class的问题
- self.赋值时使用alloc的问题
- 修复bad ELF interpreter问题
- SpringMVC 400 Bad Request 问题
- SpringMVC 400 Bad Request 问题
- SpringMVC 400 Bad Request 问题
- SpringMVC 400 Bad Request 问题
- springmvc bad 400问题总结
- SpringMVC 400 Bad Request 问题
- HDU1059:Dividing(多重背包二进制优化)
- lightOJ 1045 Digits of Factorial (数位计数)
- SlidingMenu 侧滑菜单
- sql行转列和列转行
- 求最大的数(二):利用委托改成一个入口函数
- 问题三十八:C++中bad alloc问题(1)——分析问题
- scala string to int|scala 字符串转int
- alertController的封装(在TYAlertController基础上封装)
- 我要AK
- 树的子结构
- 挑战程序设计竞赛 POJ 3253 贪心+霍夫曼思想+优先队列
- java零基础入门知识1.0——java基本工具介绍
- A - Table Decorations codeforces 487C
- poj 1328 Radar Installation