Timo
Timo

Reputation: 3

wrong output of programm, using pointers to an array of structs

Im trying to run a simulation and create points as structs. I now want to store them in an array and tried to use a pointer on that array. When i run the programm, it just randomly gives me a wrong output. I suspect there is something wrong with the pointer "Point *Point" or the use of the malloc() funtion. when Im changing things it only gets worse and the programm doesnt even finish and gives me this error code: Process returned -1073741819 (0xC0000005)

I'd very happy if someone knew why its failing :)

This is my code

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

#define M_PI 3.14159265

//mx..+bx.+kx=p*sgn(x.)

double p=1;
double m=1;
double const_b=1;
double const_k=1;

typedef struct point{
    double counter;
    double x;
    double xDot;
}Point;

double DGL(double x, double xDot){
    int sgn=0;
    if(xDot>0){
        sgn=1;
    }
    else{
        sgn=-1;
    }
    double xDotDot = -const_b/m*xDot-const_k/m*x+p/m*sgn;
    return xDotDot;
}

Point *runSimulation(double time, double x_0, double step)
{
    double x=x_0;
    double xDot=0;
    double xDotDot=0;
    double counter=0;
    int i=0;

    Point *Point= malloc(time/step*sizeof(Point));

    while(counter<time)
    {
        xDotDot=DGL(x, xDot);
        xDot=xDot+xDotDot*step;
        x=x+xDot*step;

        Point[i].x=x;
        Point[i].xDot=xDot;
        Point[i].counter=counter;

        counter = counter + step;
        i++;
    }

    return Point;
}

void printSimulation(Point *Point, int length, FILE* datei)
{
    for(int i=0; i<length; i++)
    {
        //fprintf(datei, "%.2f ; %.2f ; %.2f\n", Point[i].counter, Point[i].x, Point[i].xDot);
        printf("t=%.3f[s] ; x=%.3f[m] ; x_punkt=%.3f[m/s]\n", Point[i].counter, Point[i].x, Point[i].xDot);
    }
}

int main()
{
    double x=0, xDot=0, xDotDot=0, x_0=0;
    double step=0.1, counter=0, time=2;
    double timeTol=0.05;
    double dauerT=0, lastCount=0;

    Point *PhasePtr;

    //Datei für Results öffnen
    FILE* datei = fopen("selbsterregte Schwingung_results.csv", "a");

    if(datei==NULL){
        printf("Fehler bei Dateizugriff");
        return 1;
    }

    //Parameter eingeben
    printf("Simulationsparamter eingeben \nDämpfungsfaktor b:");
    scanf("%lf", &const_b);
    printf("Startauslenkung x,0=");
    scanf("%lf", &x_0);
    printf("Simulationsdauer I:");
    scanf("%lf", &time);
    fflush(stdin);
    int length=time/step;

    //Simulation läuft
    PhasePtr=runSimulation(time, x_0, step);

    //Ergebnisse auf Bildschirm und in Datei gespeichert
    printSimulation(PhasePtr, length, datei);

    fclose(datei);
    return 0;
}

this is the wrong output (obviously the long numbers and the nulls in between are the wrong ones)

t=1.600[s] ; x=-0.502[m] ; x_punkt=-0.975[m/s]
t=1.700[s] ; x=-0.595[m] ; x_punkt=-0.928[m/s]
t=1.800[s] ; x=-0.682[m] ; x_punkt=-0.875[m/s]
t=1.900[s] ; x=-0.764[m] ; x_punkt=-0.820[m/s]
t=2.000[s] ; x=-0.840[m] ; x_punkt=-0.761[m/s]
t=2.100[s] ; x=-0.911[m] ; x_punkt=-0.701[m/s]
t=179538685518702200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[s] ; x=0.000[m] ; x_punkt=11186857329615961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=179538516283209850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[s] ; x=195426269015847380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=0.000[s] ; x=0.000[m] ; x_punkt=0.000[m/s]
t=78973501660828132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[s] ; x=0.000[m] ; x_punkt=14621964126845871000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000[m/s]
t=3.900[s] ; x=-1.096[m] ; x_punkt=0.779[m/s]
t=4.000[s] ; x=-1.005[m] ; x_punkt=0.911[m/s]
t=4.100[s] ; x=-0.903[m] ; x_punkt=1.020[m/s]
t=4.200[s] ; x=-0.792[m] ; x_punkt=1.108[m/s]
t=4.300[s] ; x=-0.675[m] ; x_punkt=1.177[m/s]
t=4.400[s] ; x=-0.552[m] ; x_punkt=
and so on

Upvotes: 0

Views: 87

Answers (3)

Mike Stallone
Mike Stallone

Reputation: 52

I can see a decent amount of issues in this code which could be causing this problem:

  1. names duplicated everywhere in differing contexts:
  • You can confuse the compiler (and yourself, realistically) if you name your struct the same thing as your type. When you type Point, is it referring to the struct type or the struct? It's up to the compiler, and it might be getting confused and using the wrong one. This is not the only issue of this in the code, but it is the worst offender
  1. It's not clear to me what math operations you're trying to do with your code, and even less so to the compiler:

double xDotDot = -const_b/mxDot-const_k/mx+p/m*sgn;

  • With the above statement, do you want the compiler to do (xDot*const_b)/m? Because that's how it will be evaluated
  1. Malloc with doubles

Point* pnt = malloc(time / step * sizeof(Point));

  • this really should not be done. Convert this to the correct type first, ie. uint32_t
  • since you're not explicitly determining type, the compiler could assume that you are doing math with uint32_t values, in which case 0.1 will be converted to 0, and your equation will be interpreted as the below, which will obviously cause issues with your program:

Point* pnt = malloc(time/0* sizeof(Point));

  1. You shouldn't malloc in a function:
  • malloc the size of your pointer-array in the main, pass the pointer to said array into your function. You then won't have to deal with any of the clunkiness of returning a struct-pointer, and it's good practice for malloc for the future; you want to make it as obvious as possible that you've allocated memory, so you don't run into a scenario where your code continues to allocated memory forever until there's no space left on your processor

Upvotes: 0

chux
chux

Reputation: 153348

At least these problems:

  1. Point *Point= malloc(time/step*sizeof(Point)); is dodgy as it can under allocate due to fraction truncation.

In general, better to use integer math to find allocation needs and use the same to iterate the loop.

  1. Point *Point= malloc(time/step*sizeof(Point)) muddies the water: Is that size of the type or pointer? Use different names to be clear.

//                            Pass in length---v
Point *runSimulation(double time, double x_0, int length)
{
    double step = time/length;
    double x=x_0;
    double xDot=0;
    double xDotDot=0;
    double counter=0;
    int i=0;

    // Point *Point= malloc(length*sizeof(Point));
    Point *P = malloc(length * sizeof *P);

    // while(counter<time)
    for (i=0; i<length; i++) {
        xDotDot = DGL(x, xDot);
        xDot = xDot+xDotDot*step;
        x = x+xDot*step;

        // P, not Point
        P[i].x = x;
        P[i].xDot = xDot;
        P[i].counter = counter;

        counter = counter + step;
        // i++;
    }

    return P; // P
}

and call

PhasePtr = runSimulation(time, x_0, length);

"%g"

Tip: Use "%.3g" to print double instead of %.3f as it handles large and wee values better.

Upvotes: 1

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

Don't name your pointer variable the same as the type Point.

Example:

Point* runSimulation(double time, double x_0, double step) {
    double x = x_0;
    double xDot = 0;
    double xDotDot = 0;
    double counter = 0;
    int i = 0;

    // is this formula really correct?
    Point* pnt = malloc(time / step * sizeof(Point));

    while(counter < time) {
        xDotDot = DGL(x, xDot);
        xDot = xDot + xDotDot * step;
        x = x + xDot * step;

        pnt[i].x = x;
        pnt[i].xDot = xDot;
        pnt[i].counter = counter;

        counter = counter + step;
        i++;
    }

    return pnt;
}

You should also do free(PhasePtr); in main to free the memory after you're done.

Upvotes: 1

Related Questions