0

As the title explains I have a set of variables the objective is to print them in a file iteratively updating them every time, but for some reason I am no able to print the variable value, I am relatively new to C and finding pointers a little bit complicated to handle, my guess is the problem is about memory assignation.

Due to the length of it I present a shorter but equivalent version of my code:

#include <stdlib.h>
#include <math.h>
#include <stdio.h>

int main()
{
    int n = 2;
    FILE *in;
    char filename1[30] = "positions.txt";
    double *x_tp, *y_tp, *z_tp;
    double *x_tf, *y_tf, *z_tf;
    *x_tp = 1.0;
    *y_tp = 0.0;
    *z_tp = 0.0;
    in = fopen(filename1, "w");
    fprintf(in,"%lf \t %lf \t %lf\n",x_tp,y_tp,z_tp);
    fclose(in);
    in = fopen(filename1, "w");
    for (i = 1; i <= n; i++)
    {
        *x_tf = x_tp + "somefunctionx";
        *y_tf = y_tp + "somefunctiony";
        *z_tf = z_tp + "somefunctionz";
        fprintf(in,"%lu \t %lu \t %lu\n",x_tf,y_tf,z_tf);
        x_tp =  x_tf;
        y_tp =  y_tf;
        z_tp =  z_tf;
    }
    fclose(in);
}

*Clarification n value is meant to be much higher than 2 i just want it to be 2 for the program to run quickly so I can test it.

**If relevant somefunction is related to a runge-kutta step and the whole thing is part of a 4 body problem.

What I end up with is in fact a .txt file but instead of the values I want its all filled with "nan"s

13
  • Tip: If you are new to C etc. and struggle with pointers, use a naming scheme, here shown by example: int x; int* px; x = 42; *px = 42; So - if you have a pointer to some type, add a p to the variable name. If you want to access the type, you need as many "*" to de-reference as you have "p" in the name. If you had a int *** pppx; you still would know that to assign to it or use the value you would need 3 * to dereference. Commented Apr 19, 2015 at 23:19
  • double *x_tp, *y_tp, *z_tp; double *x_tf, *y_tf, *z_tf; *x_tp = 1.0; *y_tp = 0.0; *z_tp = 0.0; remove *. You do not need to use the pointer. Commented Apr 19, 2015 at 23:20
  • So the number of * in every iteration should also increment by one? Commented Apr 19, 2015 at 23:21
  • Its easy, really. If you have some int x = 42;, this means that there is memory at some address, which is large enough to hold an int. If you want the address, you write &x. If you have a pointer, it IS the address. int* px = &x;. If you want the value at that address, you dereference: `` int y = *px;`` Commented Apr 19, 2015 at 23:23
  • 1
    in is a somewhat confusing name for an output file. Commented Apr 19, 2015 at 23:39

2 Answers 2

1

All the variables

double *x_tp, *y_tp, *z_tp;
double *x_tf, *y_tf, *z_tf;

Are pointers to doubles If you want, meaning they are looking for address to doubles. In the code you have no doubles declared for your pointers to point to.

This is an example of pointers

#include <stdlib.h>
#include <math.h>
#include <stdio.h>

int main()
{
 int n = 2;
 FILE *in;
 char filename1[30] = "positions.txt";
 double x_tp, y_tp, z_tp;

 /*Initialize Pointers */
 double *x_tf = &x_tp, *y_tf = &y_tp, *z_tf = &z_tp;

 /* Assigns the doubles to the pointer variables & initializes variables. */
  x_tp = 1.0;
  y_tp = 0.0;
  z_tp = 0.0;

 in = fopen(filename1, "w"); /* Opens and prints variables to file */
 fprintf(in, "%lf \t %lf \t %lf\n", x_tp, y_tp, z_tp);
 fclose(in);
 in = fopen(filename1, "a"); /*Appends the new numbers to the file -- "w" will rewrite the file entirely. */
 for (int i = 1; i <= n; i++)
 {
     x_tp = 2.0; /*Example of updating the values at x_tp -- etc. Pointers will have new values. */
     y_tp = 22.0;
     z_tp = 1.0;
     /* Assigns doubles to pointers then prints the value at that pointer */
        fprintf(in, "%lf \t %lf \t %lf\n", *x_tf, *y_tf, *z_tf); /* Prints Values at each pointer -- tells the compiler to go to that pointer and print the value. */

 }
 fclose(in);

}

Your pointers needed to point to some double. You also initialize your pointers with addresses if you initialize in the declaration statement.

the "w" in your read / write for your loop would of overwritten your entire text file; "a" appends and adds to the text file.

It's not so much memory; you just needed to give your pointers addresses. If you wanted to print "somefunctionx" like in your code. You can just assign the new values then do:

 x_tp = 2.0; /*Updates pointer */
 fprintf(in, "somefunctionx : ", *x_tf);

You could also just "\n" for each subsequent variable.

Sign up to request clarification or add additional context in comments.

Comments

0

First off, you do not need to declare your variables as pointers here at all.

double x_tf, ...; 

will be more adequate. Then you can write:

x_tf = 1.0;

and later on:

printf("%f", x_tf); 

and there is no pointer problem anywhere.

IF you now have a function which has OUT or INOUT semantics arguments, such as

void RungeKuttaStep( double *pxs, double *pys ); // whatever

which semantically means that they do not only need the value but also intend to write new values to those variables, you call it with

double xs = 1.0;
double ys = 1.0;
RungeKuttaStep( &xs, &ys );
printf( "now xs = %f and ys = %f\n", xs, ys );

What you probably try to achieve is to alternate the use of your variables. After each call, you want to use the results of the previous step as new input to the next call.
To achieve that, you could write:

double a1,b1,c1; // lazily renamed your variables, mean me
double a2,b2,c2;

// probably in a loop
a1 = 1.0; b1 = 1.0; c1 = 1.0;
a2 = a1 + RungeKutta1(a1,b1,c1);
b2 = b1 + RungeKutta2(a1,b1,c1);
c2 = c1  + RungeKutta3(a1,b1,c1);
a1 = a2; b1 = b2; c1 = c2;
// probably end of loop

A double has 8 bytes of size and a pointer, depending on your OS and build has 4 or 8 bytes of data. You will not notice a difference in speed by not using pointers.

7 Comments

The problem is I tried to used pointers because when I make x_tf = 1.0; and then printf("%f", x_tf); I still get nans. does this mean the problem is somewhere else?
Possibly. Maybe the values you provide to your runge kutta functions cause it to produce NaNs as a result.
@casih You write pointers in floating point format to the file. This explains your NaNs.
But the first value doens't even go through a function, which is weird, and also yeilds nans
Because it would be pure luck if the address of a pointer happened to conform the structure of a IEEE floating point number.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.