繁体   English   中英

从(坏)数组[size]移动到array = new float [size]

[英]Moving from (bad) array[size] to array = new float[size]

我正在编写一个程序,用于为一个类找到根,并且已经完成并使其完美运行。 当我打开它时,我看到该文档需要使用Visual Studio 2012编译.cpp - 所以我试试了。 我通常使用Dev C ++ - 而且我发现它允许我编译“时髦的东西”,例如动态声明数组而不使用malloc或new运算符。

因此,在找到与我错误定义数组的错误相关的错误后 - 我尝试使用malloccallocnew / delete来解决问题 - 它一直给我内存分配错误。 整个46981239487532字节错误。

现在,我试图按照以前的方式“返回”程序,现在我甚至无法让它工作。 我甚至不完全确定如何设置数组以便在Dev C ++中工作。 这里的代码:

#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;

float newton(float a, float b, float poly[],float n, float *fx, float *derfx);
float horner(float poly[], int n, float x, float *derx);
float bisection(float a, float b, float poly[], float n, float *fx);

int main(int argc, char *argv[])
{
    float a, b, derr1 = 0, dummyvar = 0, fr1 = 0, fr0;
    float constants[argc-3];
    //float* constants = NULL;
    //constants = new float[argc-3];
    //constants = (float*)calloc(argc-3,sizeof(float));
    //In order to get a and b from being a char to floating point, the following lines are used.
    //The indexes are set relative to the size of argv array in order to allow for dynamically sized inputs. atof is a char to float converter.
    a = atof(argv[argc-2]);
    b = atof(argv[argc-1]);

    //In order to get a easy to work with array for horners method,
    //all of the values excluding the last two are put into a new floating point array
    for (int i = 0; i <= argc - 3; i++){
        constants[i] = atof(argv[i+1]);
    }

    bisection(a, b, constants, argc - 3, &fr0);
    newton(a, b, constants, argc - 3, &fr1, &derr1);
    cout << "f(a) = " << horner(constants,argc-3,a,&dummyvar);
    cout << ", f(b) = " << horner(constants,argc-3,b,&dummyvar);
    cout << ", f(Bisection Root) = " << fr0;
    cout << ", f(Newton Root) = "<<fr1<<", f'(Newton Root) = "<<derr1<<endl;
    return 0;
}
// Poly[] is the polynomial constants, n is the number of degrees of the polynomial (the size of poly[]), x is the value of the function we want the solution for.

float horner(float poly[], int n, float x, float *derx)
{
    float fx[2] = {0, 0};
    fx[0] = poly[0];  // Initialize fx to the largest degree constant.
    float derconstant[n];
    //float* derconstant = NULL;
    //derconstant = new float[n];
    //derconstant = (float*)calloc(n,sizeof(float));
    derconstant[0] = poly[0];

    // Each term is multiplied by the last by X, then you add the next poly constant. The end result is the function at X.
    for (int i = 1; i < n; i++){
        fx[0] = fx[0]*x + poly[i];
        // Each itteration has the constant saved to form the derivative function, which is evaluated in the next for loop.
        derconstant[i]=fx[0];
    }

    // The same method is used to calculate the derivative at X, only using n-1 instead of n.
    fx[1] = derconstant[0]; // Initialize fx[1] to the largest derivative degree constant.
    for (int i = 1; i < n - 1; i++){
        fx[1] = fx[1]*x + derconstant[i];
    }
    *derx = fx[1];
    return fx[0];
}

float bisection(float a, float b, float poly[], float n, float *fx)
{
    float r0 =0, count0 = 0;
    float c = (a + b)/2; // c is the midpoint from a to b
    float fc, fa, fb;
    int rootfound = 0;
    float *derx;
    derx = 0; // Needs to be defined so that my method for horner's method will work for bisection.
    fa = horner(poly, n, a, derx); // The following three lines use horner's method to get fa,fb, and fc.
    fb = horner(poly, n, b, derx);
    fc = horner(poly, n, c, derx);

    while ((count0 <= 100000) || (rootfound == 0)) { // The algorithm has a limit of 1000 itterations to solve the root.
        if (count0 <= 100000) {
            count0++;
            if ((c == r0) && (fabs(fc) <= 0.0001)) {
                rootfound=1;
                cout << "Bisection Root: " << r0 << endl;
                cout << "Iterations: " << count0+1 << endl;
                *fx = fc;
                break;
            }
            else
            {
                if (((fc > 0) && (fb > 0)) || ((fc < 0) && (fb < 0))) { // Checks if fb and fc are the same sign.
                    b = c; // If fc and fb have the same sign, thenb "moves" to c.
                    r0 = c; // Sets the current root approximation to the last c value.
                    c = (a + b)/2; // c is recalculated.
                }
                else
                {
                    a=c; // Shift a to c for next itteration.
                    r0=c; // Sets the current root approximation to the last c value.
                    c=(a+b)/2; // Calculate next c for next itteration.
                }
                fa = horner(poly, n, a, derx); // The following three send the new a,b,and c values to horner's method for recalculation.
                fb = horner(poly, n, b, derx);
                fc = horner(poly, n, c, derx);
            }
        }
        else
        {
            cout << "Bisection Method could not find root within 100000 itterations" << endl;
            break;
        }
    }
    return 0;
}

float newton(float a, float b, float poly[],float n, float *fx, float *derfx){
    float x0, x1;
    int rootfound1 = 1, count1 = 0;
    x0 = (a + b)/2;
    x1 = x0;
    float fx0, derfx0;
    fx0 = horner(poly, n, x0, &derfx0);
    while ((count1 <= 100000) || (rootfound1 == 0)) {
        count1++;
        if (count1 <= 100000) {
            if ((fabs(fx0) <= 0.0001)) {
                rootfound1 = 1;
                cout << "Newtons Root: " << x1 << endl;
                cout << "Iterations: " << count1 << endl;

                break;
            }
            else
            {
                x1 = x0 - (fx0/derfx0);
                x0 = x1;
                fx0 = horner(poly, n, x0, &derfx0);
                *derfx = derfx0;
                *fx = fx0;
            }
        }
        else
        {
            cout << "Newtons Method could not find a root within 100000 itterations" << endl;
            break;
        }
    }
    return 0;
}

所以我花了几个小时试图解决这个问题,最后,我已经放弃了询问。我看到的任何地方都只是说定义为

float* constants = NULL;
constants = new float[size];

但这会让我的程序崩溃 - 可能是因为某种程度上分配了太多的内存。 我已经用各种方式和组合评论了我尝试过的东西。 如果你想要更多tl; dr到“麻烦点”,它们就是主要和角色功能的最开始。

这是一个问题,主要是为constantsargc-3浮点数(以各种方式)分配空间,但循环中的代码写入数组的末尾。

更改:

for( int i = 0; i<=argc-3; i++){

for( int i = 0; i<argc-3; i++){

仅这一点就足以导致分配错误。

编辑:如果您使用的东西分配空间,还要注意new ,你需要删除它delete ,否则将继续使用内存,并可能耗尽(尤其是如果你在100,000循环做到这一点)。

编辑2:正如Galik在下面提到的,因为你使用derconstant = new float[n]来分配内存,你需要使用delete [] derconstant来释放内存。 当您开始为类对象分配空间时,这很重要,因为delete []表单将调用数组中每个元素的析构函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM