问题三十八: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;

 


4 0
原创粉丝点击