c++ - 从(坏的)array[size] 移动到 array = new float[size]

标签 c++ arrays floating-point

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

因此,在发现与我错误定义数组的方式相关的错误之后 - 我尝试使用 malloc 解决问题, calloc , 和 new/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 到“麻烦点”,它们位于 main 和 horner 函数的最开始。

最佳答案

这是一个问题,主要是您为 argc-3 float (以各种方式)为 constants 分配了空间,但是循环中的代码写到了数组。

改变:

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 [] 形式将调用数组中每个元素的析构函数。

关于c++ - 从(坏的)array[size] 移动到 array = new float[size],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32900669/

相关文章:

floating-point - Fortran 实数表达式中的后缀 'd+0'

c++ - WxWidgets 中的缓冲图像

sql - 在 SQL (Postgres) 中作为 JSON 对象数组返回

php - 使用php mysql将数组设置为数组中的列名

javascript - 范围总和---得到 "undefined"

Delphi错误的 double 计算

python - 浮点精度导致比较时出错

c++ - 将 NDEF 记录有效负载转换为 EthernetClient print() 的字符串

c++ - 媒体基础 SinkWriter (MP4 FastStart)

c++ - for循环中的随机数生成器每次都给出相同的数字