[英]Moving from (bad) array[size] to array = new float[size]
我正在编写一个程序,用于为一个类找到根,并且已经完成并使其完美运行。 当我打开它时,我看到该文档需要使用Visual Studio 2012编译.cpp
- 所以我试试了。 我通常使用Dev C ++ - 而且我发现它允许我编译“时髦的东西”,例如动态声明数组而不使用malloc或new运算符。
因此,在找到与我错误定义数组的错误相关的错误后 - 我尝试使用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到“麻烦点”,它们就是主要和角色功能的最开始。
这是一个问题,主要是为constants
为argc-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.