# Problem with my C++ code (MATH/Physics based)

1. Feb 6, 2016

### RJLiberator

1. The problem statement, all variables and given/known data

Here's my problem. I am working with ROOT which uses C++ and I am making 3 different graphs. This particular part of the code is for the parabolic motion with density calculation.

The problem is, that I follow the rules in the powerpoint provided to me, the other two of my plots work beautifully (with no air resistance, with air resistance are the other two plots).

This particular code provides me a crash, where it causes my ROOT to shut down.

I have messed with it for the past two hours to find that the error is in the calculation somewhere. It's possible a divide by 0 error, or some other error.

Here's the thing:

When I input fx[0]=0.208
and fy[0]=0.208
then switch the fy[ i ]'s to fy[i+1]'s everywhere, I get the program to run (it does not graph, but it runs).
When I switch the fy[0] and fx[0] components to 0.0208 it no longer runs.

So I have a feeling that there is something critically wrong with my equations, but I can't find it.

Any help looking into my code equations is appreciated.

2. Relevant equations

3. The attempt at a solution

Code (C):

void cannonefff(float h=10, float vx=10, float vy=25, float time = 0.05)

{

double g = 9.81;

float B = 0.004;  // this counts for b/m

float yax = h+(vy*vy)/(2*g);

float root = sqrt(vy*vy+2*h*g);

float t0 = (vy+root)/g;

float xax = t0*vx;

cout<<"The time that the projectile will be in the air is: "<<xax<<endl;

TCanvas *c1 = new TCanvas("c1","Parabolic Motion",200,10,700,500);

c1->SetGrid();

// draw a frame to define the range

TH1F *hr = c1->DrawFrame(-100,-300,xax*1.2,300);

hr->SetTitle("Parabolic Motion");

hr->SetXTitle("Time [s]");

hr->SetYTitle("Position [m]");

c1->GetFrame()->SetBorderSize(12);

float x[2000], y[2000], fx[2000], fy[2000], vx[2000], vy[2000];

vx[0]=vx;

vy[0]=vy;

x[0]=0;

y[0]=h;

//float fx[0]=-0.0208

//float fy[0]=-0.0208

float z = 10000;

float v;

Int_t n=2000;

for(Int_t i=0; i<n-1; i++);

{

v = sqrt(vx[ i ]*vx[ i ]+vy[i]*vy[ i ]);

fx[i+1] = -exp(-y[ i ]/z)*B*v*vx[ i ];

fy[i+1] = -exp(-y[ i ]/z)*B*v*vy[ i ];

x[i+1]=x[ i ]+vx[ i ]*time;

vx[i+1] = vx[ i ]+fx[i+1]*time;

y[i+1]=y[ i ]+vy[ i ]*time;

vy[i+1]=vy[ i ]-g*time+fy[i+1]*time;

}

Last edited by a moderator: Feb 6, 2016
2. Feb 6, 2016

### Staff: Mentor

Have you tried running it in a debugger?

Crashes usually occur when you've referenced a pointer and stored something out of bounds of ypur array or the pointer was never initialized somehow.

A common problem that programmers run into is a local variable string array of say 10 chars and then pass it to some subroutine which then writes more than 10 chars into it. C++ allocates memory on the stack for the local array and more for the called subroutine and now you've just overwritten data in your stack that your subroutine needed to return and BOOM program crash. A debugger can help you analyze things before they crash.

In your case, you have a lead in that you know its got something to do with fx and fy arrays so check the indexing of these arrays and the sizes you've allocated and then then referencing of things.

Another odd feature of C/C++ is that sometimes your debugging print statements can mask the situation meaning your program will run and not crash but commenting them out causes the crash. Go figure, this happened to me once and I found that they had adjusted the stack just so to avoid the crash ie different data on the stack.

I did notice that the edge case of i+1 in your loop could reference one element past your array in fy right?
n=2000 and the loop is 0 to 1999 and the arrays are 0..1999 so the i+1 at 1999 is 2000 which is one element beyond. You could try allocating a few more elements to see if the crash vanishes, it won't eliminate the error necessarily but may eliminate the crash.

Last edited: Feb 6, 2016
3. Feb 6, 2016

### Wee-Lamm

I was a little curious about
vx[0]=vx;

It seems odd to me to see an array element populated from a non-array of the same name.

fx[i+1] = -exp(-y[ i ]/z)*B*v*vx[ i ] ;
fy[i+1] = -exp(-y[ i ]/z)*B*v*vy[ i ];

Are negative exponents allowed?

Last edited by a moderator: Feb 6, 2016
4. Feb 6, 2016

### RJLiberator

Thanks guys for the helpful motivation.

I just started a new code, from the same sort of style.
I'm sure I must have changed something, but it worked.

Originally, I was letting B = 0.004 and 'accounting for mass'
But I switched the style and let b = 0.03 and m = 100, and somehow it worked magically.

My new code for the main part is :

Code (C):

for (Int_t i=0; i<n-1; i++)
{
v = sqrt(vx[i]*vx[i]+vy[i]*vy[i]);
fx[i]=-exp(-y[i]/f)*b*v*vx[i];
fy[i]=-exp(-y[i]/f)*b*v*vy[i];
x[i+1]=x[i]+vx[i]*time;
vx[i+1]=vx[i]+fx[i]*time/m;
y[i+1]=y[i]+vy[i]*time;
vy[i+1]=vy[i]-g*time+fy[i]*time/m;
}

And my variables
Code (C):

float x[2000], y[2000], w[2000], fx[2000], fy[2000], z[2000], k[2000], p[2000], vx[2000], vy[2000], vx2[2000], vy2[2000], vx3[2000], vy3[2000];
vx2[0]=vx;
vy2[0]=vy;
vx[0]=vx;
vy[0]=vy;
vx3[0]=vx;
vy3[0]=vy;
k[0]=0;
p[0]=h;
x[0]=0;
y[0]=h;
w[0]=0;
z[0]=h;

float f = 10000;
float v2;
float v;
Thank you much. It seems to be working now.

5. Feb 6, 2016

### Staff: Mentor

Closing the thread temporarily to fix the problem with extraeous italics. I'll open it back up in a few minutes.

@RJLiberator, be careful when you write array elements using i for an array index. The forum software mistakenly interprets this is a BBCode italics tag.

Edit: The thread is open again.

6. Feb 6, 2016

### Staff: Mentor

You really should indent the body of for and other loops.
Aside from that, when you have an array element such as vx[i], try to remember to write it with extra spaces, as vx[ i ]. Otherwise the forum software renders it as just vx, and renders any following characters as italic.
All of the assignment statements above are flaky. vx2[0] and all of the other 5 variables are of type float. vx and vy are of type "array of float". That is, vx and vy are addresses. Your compiler should be issuing warnings for each of the six statements above.

7. Feb 6, 2016

### Staff: Mentor

Yes, this is odd, and it is likely a logical error.

vx is the name of an array, so it evaluates to the address in memory of the first element of the array, vx[0]. In other words, the statement above is equivalent to:
Code (C):
vx[0] = &vx[0]
Yes, of course. The exp() function is defined for all real numbers

8. Feb 6, 2016

### RJLiberator

Thank you for the tip. I am getting more experienced with coding, and as a highly organized individual, I appreciate the beautification of coding. However, the learning process can take a toll on my code. In the future, it should get better.
I did take note of your code = c from last time :).

Thank you.

9. Feb 6, 2016

### Staff: Mentor

Here's a declaration in your code:
Code (C):
float x[2000];
Let's suppose that the compiler stores this array at a hypothetical memory address of 6020. This means that x[0] will be stored in locations 6020 through 6023 (four bytes), and x[1] will be stored at locations 6024 through 6027, and so on up to and including x[1999], the last element in the array.

Let's look at this statement, similar to several in your code:
Code (C):
x[0] = x;
The result here is that the address of the array (i.e., the address of the first element of the array, or 6020) is stored in x[0]. The compiler will issue a warning, because the type of the variable x[0] is float, while the type of x is "array of float", or really, pointer to float.

I don't know what you were trying to do with those six statements I commented on, but I'm certain you didn't intend to be storing addresses in the array elements.

10. Feb 6, 2016

### Wee-Lamm

vx and vy are first declared as floats in the function declaration.
They are then declared as array of floats within the function, just prior to the for loop.

I wonder if changing the names in the declaration would help?
It seems strange to declare these parameters with values which would overwrite any values sent from calling this function.

void cannonefff(float h=10, float vx=10, float vy=25, float time = 0.05)

could become,
void cannonefff(float& in_h, float& in_vx, float& in_vy, float& in_time)
{
in_h = 10;
in_vx = 10;
in_vy = 25;
in_time = 0.05;
}

I would also be uncomfortable using "time" as a variable name, on the chance I chose to later include the time class for some purpose.

11. Feb 6, 2016

### Inventive

C/c++ are susceptible to fence post errors.. A fence post error occurs when you index an array outside the size for which it was defined. Based on what I see can you honestly guarantee "n" will always be in the range of your arrays? One use of try catch blocks are to provide temporary exception handling that prevents the stack from unwinding and letting the operating system catch your error. C/C++ is language that requires planning in writing code because of the use of pointer variables. Debugging software is a skill that takes years to perfect; it is important to know what tools you have for debugging and practice using them. Debugging also requires creativity and intuition. I would also like to recommend that you do not use non descriptive variable names. If you or someone else tries to understand what you are doing in the future the code will probably be re-written. Also break the calculations into separate lines since it can be very difficult to debug code even with a debugger. In many cases a debugger is useless when code is compacted onto one line. I am being critical because I am trying to help. In part of my 35 year professional career I have written code in C/C++, C#, and assembly language and I have made these mistakes in the past.

Last edited: Feb 6, 2016
12. Feb 6, 2016

### Staff: Mentor

You make a good point, but I suspect that the code you pasted above was not part of a single function, as you show here. It's a syntax error to redefine a function parameter; i.e., with vx first defined as a parameter of type float, and then later as an array of float.

Last edited: Feb 7, 2016
13. Feb 7, 2016

### Inventive

Try commenting out all of those complex single line expressions and then un comment out each one - one
At a time and run the program; its iterive, but maybe a line of code is generating
a value that causes it to crash. Try commenting everything out and uncommenting one statement at a time
It could be statements like the vx[0] = vx is causing trouble.
It is possible the problem is arising somewhere else depending on how your overall project is structured