Zugriffsverletzung

Neue Frage »

Auf diesen Beitrag antworten »
kein_plan Zugriffsverletzung

Meine Frage:
Hallo,

ich hab folgendes Programm geschrieben, das den Sinus durch ein Taylopolynom berechnet und im Intervall [-2;2] die maximale Differenz dieser Approximation zum vorimplementierten Sinus in math.h bestimmen soll:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
#include <stdio.h>
#include <math.h>

#define GRAD 22
#define SCHRITTWEITE 0.01f

double sinus_taylor(double x)
{
	short i;
	double ergebnis = 1.0;

	for(i=GRAD; i>=1; i--)
		ergebnis = 1-ergebnis*x*x/(2*i*(2*i+1));

	return x*ergebnis;
}

double betrag(double x) {return (x>0 ? x : -x);}

int main()
{
	double x=0, sup = 0;
	
	for(x=-2; x<=2; x+=SCHRITTWEITE)
		if(sup<betrag(sinus_taylor(x)-sin(x)))
			sup = betrag(sinus_taylor(x)-sin(x));
	
	printf("Die maximale Differenz zwischen der vorimplementierten Sinus-Funktion und dem \
Taylorpolynom vom Grad %i beträgt %d. Dieser Wert ist %s als 10^(-15).\n\n", GRAD, sup, sup<pow(10.0, -15) ? "kleiner" : "groesser");

	getchar();
	
	return 0;
}


Wenn ich das Programm ausführe kommt jedoch folgende Fehlermeldung:
Unbehandelte Ausnahme bei 0x774216B3 (msvcr110d.dll) in Blatt_7_2_2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x3CB00000

Meine Ideen:
Woran liegt das?
Ich glaube, es muss an der for-Schleife (Zeilen 24 - 26) liegen. Denn wenn ich die aus dem Code rausnehme, gibt es keinen Fehler beim Ausführen des Programms.
 
Auf diesen Beitrag antworten »
eulerscheZahl

Die Logik dahinter habe ich mir noch nicht angeschaut, aber der Fehler ist:
printf("... vom Grad %i beträgt %d....", GRAD, sup, ...);
sup ist ein double, du willst es aber mit %d ausgeben.
Auf diesen Beitrag antworten »
kein_plan

Stimmt, das habe ich wohl übersehen. Aber wenn ich die komplette for-Schleife weglasse, funktioniert es. Warum? sup ist doch dann trotzdem eine double-Variable. Liegt es daran, dass der Wert von sup dann 0 ist?

Zitat:
Original von eulerscheZahl
Die Logik dahinter habe ich mir noch nicht angeschaut

Was meinst du damit?
Auf diesen Beitrag antworten »
eulerscheZahl

Warum es ohne die for-Schleife funktioniert, kann ich dir leider nicht beantworten - mit Visual Studio funktioniert es auch mit Schleife und fehlerhafter Ausgabe.

Mit der Logik dahinter meinte ich die Funktion sinus_taylor, die ausgegebenen Werte passen aber - ist nur extrem unleserlich.
Etwas leserlicher und trotzdem effizient in der Laufzeit:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
double sinus_taylor(double x)
{
	short i;
	double ergebnis = 0;
	double fakultaet = 1;
	double x_potenz = x;
	//sin(x) = x/1! - x^3/3! + x^5/5! - x^7/7! + ...
	for(i=1; i <= GRAD; i+=2)
	{
		ergebnis += x_potenz/fakultaet * (i%4==1 ? 1 : -1);
		x_potenz *= x*x;
		fakultaet*=(i+1)*(i+2);
	}
	return ergebnis;
}
 
Auf diesen Beitrag antworten »
kein_plan

Zitat:
Original von eulerscheZahl
Warum es ohne die for-Schleife funktioniert, kann ich dir leider nicht beantworten - mit Visual Studio funktioniert es auch mit Schleife und fehlerhafter Ausgabe.

Ich hab ja mit Visual Studio kompiliert, und da gab es diese Fehlermeldung.


Die Funktion sinus_taylor lasse ich, glaube ich, so. In der Vorlesung haben wir das mit der e-Funktion so ähnlich gemacht. Etwas unleserlich ist es schon. Aber wenigstens kommen die richtigen Werte raus. Augenzwinkern


Mal noch eine Frage zu Visual Studio: Wenn ich das kompiliert habe, wird ja eine exe-Datei erstellt. Beim nächsten Kompilieren kommt dann die folgende Fehlermeldung:
fatal error LNK1168: "C:\Users\Su\documents\visual studio 2012\Projects\Blatt_7_2_2\Debug\Blatt_7_2_2.exe" kann nicht zum Schreiben geöffnet werden.
Wenn ich die exe wieder lösche, kann ich danach wieder kompilieren. Allerdings nur einmal: Dann kommt wieder das gleiche Problem. Weißt du auch, woran das liegt?
Auf diesen Beitrag antworten »
kein_plan

Übrigens: Wenn ich ein paar Minuten warte, geht es wieder von alleine, ohne, dass ich die alte exe-Datei löschen muss.
Auf diesen Beitrag antworten »
eulerscheZahl

Nochmal getestet: Visual Studio 2010 führt das Programm aus, Visual Studio 2012 und der gcc verursachen einen Absturz.

Zum Linkerfehler: ist mir noch nicht untergekommen, möglicherweise ist das Programm nicht richtig beendet worden, kann auch mit dem Virenscanner zusammenhängen.
Auf diesen Beitrag antworten »
kein_plan

Ich hab Visual Studio 2012.

Das Programm beende ich, indem ich in Visual Studio auf den Button "Debugging beenden" klicke (oder Umschalt+F5). Also sollte es ja dann richtig beendet sein, oder? Und das Virenprogramm möchte ich auch nicht abschalten.
Auf diesen Beitrag antworten »
eulerscheZahl

Zitat:
Original von kein_plan
Ich hab Visual Studio 2012.

Weiß ich, ging aus deiner Fehlermeldung hervor Augenzwinkern

"Debugging beenden" ist richtig, aber trotzdem glaube ich, dass es nicht ganz beendet wurde, warum sonst der fehlende Schreibzugriff...
Was du hier beschreibst klingt sehr ähnlich wie das hier.
Auf diesen Beitrag antworten »
kein_plan

Ja, das scheint das selbe Problem zu sein. Da gehts auch um das Virenprogramm, das ich nutze. Ich gucke mal, ob/wie ich bei meinem Virenprogramm Ausnahmen festlegen kann.

Vielen Dank, dass du mir (mal wieder) so super geholfen hast! smile
 
Neue Frage »
Antworten »


Verwandte Themen