程序输出错误,使用指向结构数组的指针
wrong output of programm, using pointers to an array of structs
我正在尝试 运行 模拟并将点创建为结构。我现在想将它们存储在一个数组中并尝试在该数组上使用一个指针。当我 运行 程序时,它只是随机地给我一个错误的输出。我怀疑指针“Point *Point”或 malloc() 函数的使用有问题。当我改变事情时,它只会变得更糟,程序甚至没有完成并给我这个错误代码:进程返回 -1073741819 (0xC0000005)
如果有人知道它失败的原因,我会很高兴:)
这是我的代码
#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;
}
这是错误的输出(很明显,长数字和中间的空值是错误的)
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
不要将您的指针变量命名为与类型相同的类型 Point
。
示例:
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;
}
您还应该在 main
中执行 free(PhasePtr);
以在完成后释放内存。
至少这些问题:
Point *Point= malloc(time/step*sizeof(Point));
是狡猾的,因为它可能由于分数截断而分配不足。
一般来说,最好使用整数数学来查找分配需求并使用它来迭代循环。
Point *Point= malloc(time/step*sizeof(Point))
搅浑水:那是类型的大小还是指针的大小?使用不同的名称是为了清楚。
// 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
}
并致电
PhasePtr = runSimulation(time, x_0, length);
"%g"
提示:使用 "%.3g"
打印双精度而不是 %.3f
,因为它可以更好地处理大值和小值。
我可以看到这段代码中有很多问题可能导致了这个问题:
- 在不同上下文中到处重复的名称:
- 如果您将结构命名为与您的类型相同的名称,您可能会混淆编译器(实际上还有您自己)。当您键入 Point 时,它指的是结构类型还是结构?这取决于编译器,它可能会感到困惑并使用错误的编译器。这不是代码中唯一的问题,但却是最严重的问题
- 我不清楚您要对代码进行哪些数学运算,编译器更不清楚:
double xDotDot = -const_b/mxDot-const_k/mx+p/m*sgn;
- 有了上面的语句,你想让编译器做(xDot*const_b)/m吗?因为这就是评估的方式
- 带双打的 Malloc
Point* pnt = malloc(time / step * sizeof(Point));
- 这真的不应该这样做。首先将其转换为正确的类型,即。 uint32_t
- 由于您没有明确确定类型,编译器可能会假设您正在使用 uint32_t 值进行数学计算,在这种情况下 0.1 将转换为 0,并且您的等式将被解释为以下内容,这显然会导致您的程序出现问题:
Point* pnt = malloc(time/0* sizeof(Point));
- 你不应该在函数中 malloc:
- 在 main 中 malloc 您的指针数组的大小,将指向该数组的指针传递给您的函数。然后你就不必处理任何返回结构指针的笨拙,这对未来的 malloc 来说是一个很好的做法;你想让它尽可能明显地表明你已经分配了内存,所以你不会 运行 进入你的代码继续永远分配内存直到你的处理器上没有 space 的场景
我正在尝试 运行 模拟并将点创建为结构。我现在想将它们存储在一个数组中并尝试在该数组上使用一个指针。当我 运行 程序时,它只是随机地给我一个错误的输出。我怀疑指针“Point *Point”或 malloc() 函数的使用有问题。当我改变事情时,它只会变得更糟,程序甚至没有完成并给我这个错误代码:进程返回 -1073741819 (0xC0000005)
如果有人知道它失败的原因,我会很高兴:)
这是我的代码
#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;
}
这是错误的输出(很明显,长数字和中间的空值是错误的)
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
不要将您的指针变量命名为与类型相同的类型 Point
。
示例:
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;
}
您还应该在 main
中执行 free(PhasePtr);
以在完成后释放内存。
至少这些问题:
Point *Point= malloc(time/step*sizeof(Point));
是狡猾的,因为它可能由于分数截断而分配不足。
一般来说,最好使用整数数学来查找分配需求并使用它来迭代循环。
Point *Point= malloc(time/step*sizeof(Point))
搅浑水:那是类型的大小还是指针的大小?使用不同的名称是为了清楚。
// 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
}
并致电
PhasePtr = runSimulation(time, x_0, length);
"%g"
提示:使用 "%.3g"
打印双精度而不是 %.3f
,因为它可以更好地处理大值和小值。
我可以看到这段代码中有很多问题可能导致了这个问题:
- 在不同上下文中到处重复的名称:
- 如果您将结构命名为与您的类型相同的名称,您可能会混淆编译器(实际上还有您自己)。当您键入 Point 时,它指的是结构类型还是结构?这取决于编译器,它可能会感到困惑并使用错误的编译器。这不是代码中唯一的问题,但却是最严重的问题
- 我不清楚您要对代码进行哪些数学运算,编译器更不清楚:
double xDotDot = -const_b/mxDot-const_k/mx+p/m*sgn;
- 有了上面的语句,你想让编译器做(xDot*const_b)/m吗?因为这就是评估的方式
- 带双打的 Malloc
Point* pnt = malloc(time / step * sizeof(Point));
- 这真的不应该这样做。首先将其转换为正确的类型,即。 uint32_t
- 由于您没有明确确定类型,编译器可能会假设您正在使用 uint32_t 值进行数学计算,在这种情况下 0.1 将转换为 0,并且您的等式将被解释为以下内容,这显然会导致您的程序出现问题:
Point* pnt = malloc(time/0* sizeof(Point));
- 你不应该在函数中 malloc:
- 在 main 中 malloc 您的指针数组的大小,将指向该数组的指针传递给您的函数。然后你就不必处理任何返回结构指针的笨拙,这对未来的 malloc 来说是一个很好的做法;你想让它尽可能明显地表明你已经分配了内存,所以你不会 运行 进入你的代码继续永远分配内存直到你的处理器上没有 space 的场景