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

  • Comp Sci
  • Thread starter RJLiberator
  • Start date
  • Tags
    C++ Code
In summary, the conversation discusses a problem with a code for ROOT, which uses C++ and creates three graphs for parabolic motion with density calculation. The problem arises when the code is run, causing ROOT to shut down. The speaker has tried various adjustments to the code, but has not been able to find the source of the error. Others suggest using a debugger and checking the indexing and sizes of arrays. The speaker then shares a new code that works, using different values for variables.
  • #1
RJLiberator
Gold Member
1,095
63

Homework Statement



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.

Homework Equations

The Attempt at a Solution



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:
Physics news on Phys.org
  • #2
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:
  • Like
Likes RJLiberator
  • #3
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.

However, in your For loop...
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:
  • Like
Likes RJLiberator
  • #4
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 :

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
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
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.
 
  • Like
Likes RJLiberator
  • #6
RJLiberator said:
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 :

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;
}
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.
RJLiberator said:
And my variables
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;
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.
RJLiberator said:
C:
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.
 
  • Like
Likes RJLiberator and Wee-Lamm
  • #7
Wee-Lamm said:
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.
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:
C:
vx[0] = &vx[0]
Wee-Lamm said:
However, in your For loop...
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?
Yes, of course. The exp() function is defined for all real numbers
 
  • Like
Likes RJLiberator
  • #8
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.
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 :).

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.

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:
Hm, I see your point. I will try to learn more about this.

Thank you.
 
  • #9
Here's a declaration in your 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:
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.
 
  • Like
Likes RJLiberator
  • #10
RJLiberator said:
[snip]
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.

C:
void cannonefff(float h=10, float vx=10, float vy=25, float time = 0.05)
{
[snip] 
float x[2000], y[2000], fx[2000], fy[2000], vx[2000], vy[2000];
vx[0]=vx;
vy[0]=vy;
     [snip]
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;
    }

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.
 
  • Like
Likes RJLiberator
  • #11
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:
  • Like
Likes Wee-Lamm and RJLiberator
  • #12
Wee-Lamm said:
C:
void cannonefff(float h=10, float vx=10, float vy=25, float time = 0.05)
{
[snip]
float x[2000], y[2000], fx[2000], fy[2000], vx[2000], vy[2000];
vx[0]=vx;
vy[0]=vy;
     [snip]
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;
    }

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.
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:
  • #13
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
 

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

1. Why is my code not giving the expected output?

There could be several reasons why your code is not giving the expected output. It could be due to a logical error in your code, incorrect use of mathematical or physics formulas, or incorrect data input. Double-check your code and make sure all the variables and formulas are correct.

2. How do I debug my code?

To debug your code, you can use a debugger tool or add print statements at different stages of your code to track the values of variables and identify where the error occurs. You can also use online resources or seek help from a colleague or a programming community.

3. How do I optimize my code for better performance?

To optimize your code, you can use efficient algorithms, avoid unnecessary loops, and use appropriate data structures. You can also use compiler optimizations and avoid using unnecessary libraries or functions.

4. How do I handle errors in my code?

To handle errors in your code, you can use try-catch blocks or error handling mechanisms provided by your programming language. You can also use conditional statements to handle specific types of errors and provide appropriate error messages.

5. How can I improve my coding skills for math and physics-based problems?

To improve your coding skills for math and physics-based problems, you can practice regularly, solve challenging problems, and read and understand the logic behind existing code. You can also take online courses or attend workshops to learn more about efficient coding techniques for these types of problems.

Similar threads

Replies
6
Views
1K
Replies
3
Views
2K
Replies
4
Views
1K
Replies
15
Views
2K
Replies
15
Views
6K
Replies
9
Views
2K
Replies
5
Views
2K
Back
Top