Unbekannter Bug in C Program - Bitte um Hilfe
-
Hallo allerseits, ich habe ein sehr nerviges Problem mit einem Program, das ich im Moment schreibe und hab den Bug bisher leider nicht finden koennen. Ich hab zigmal meinen Code von vorne bis hinten durchgesehen aber leider hat keiner der Fehler die ich gefunden habe das Problem behoben. Ich hab ausserdem gdb benutzt, aber auch das hat nicht geholfen da das Program nichts macht unter gdb.
Der Fehler ist, dass nichts(!!) passiert, also nicht einmal die printfs ausgedruckt werden die ich zur Fehlerfindung eingefuegt hab. Die Datei wird erstellt aber sie ist vollkommen leer.
Ich habe mittlere C Erfahrung wuerde ich sagen (lerne es seit einem Jahr regelmaessig). Das Program simuliert das Ising Modell in ferromagnetischen Materiallien. Ich hab urspruenglich einen pointer zu einem pointer erstellt um ein zweidimensionales array mit variabler Groesse (was sonst nicht moeglich ist) zu bekommen. Das hab ich zum debuggen aber entfernt. Ausserdem ist dieverse Code auskommentiert (so der Command line input).Hier der Code - herzlichen Dank fuer jede Hilfe!!!
#include <stdio.h> #include <stdlib.h> #include <math.h> /* Don't forget to link the maths library when compiling the program -lm */ #include <time.h> int main() { printf("h"); // Declaring variables, end: total no of sweeps, N:lattice size NxN // B and J are actually B/KT etc. int end=500, N=10; int i, j, k, l, m, n; int mod=0; int spin[10][10]; double M=0.0, CM=0.0; double B=0, J=0.4; double z; FILE *fout; double coupen = 0.0, exten = 0.0, energy=0.0; double dcoupen = 0.0, dexten = 0.0, dE = 0.0; double dspin = 0.0; double r; // Get command line input printf("hello"); // switch (argc) // { //case 7: // sscanf(argv[6], "%d", &N); //case 6: // sscanf(argv[5], "%d", &mod); //case 5: // sscanf(argv[4], "%d", &end); //case 4: // sscanf(argv[3], "%lf", &B); //case 3: // sscanf(argv[2], "%lf", &J); // } printf("1"); // Setting up the lattice //COMMENTED OUT: **spin = malloc(sizeof(int)); for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { spin[i][j] = 1; } } printf("test1"); if ((fout = fopen("output.data", "w")) == NULL) { printf("Cannot open file output.data\n"); exit(EXIT_FAILURE); } // Simulation // Get energy, remember not to count it twice and the periodic bc printf("start sim"); for(k=0;k<=(N-1);k++) { for(l=0;l<=(N-1);l++) { coupen += (k==0 && l==0) ? spin[k][l] * (spin[(N-1)][l] + spin[k+1][l] + spin[k][(N-1)] +spin[k][l+1]) : (k==0 && l!=0 && l!=(N-1)) ? spin[k][l] * (spin[(N-1)][l] + spin[k+1][l] + spin[k][l-1] + spin[k][l+1]) : (k=0 && l==(N-1)) ? spin[k][l] * (spin[(N-1)][l] + spin[k+1][l] + spin[k][l-1] +spin[k][0]) : (k!=0 && k!=(N-1) && l==0) ? spin[k][l] * (spin[k-1][l] + spin[k+1][l] + spin[k][(N-1)] + spin[k][l+1]) : (k=(N-1) && l==0) ? spin[k][l] * (spin[k-1][l] + spin[0][l] + spin[k][(N-1)] +spin[k][l+1]) : (k!=0 && k!=(N-1) && l==(N-1)) ? spin[k][l] * (spin[k-1][l] + spin[k+1][l] + spin[k][l-1] + spin[k][0]) : (k==(N-1) && l!=0 && l!=(N-1)) ? spin[k][l] * (spin[k-1][l] + spin[0][l] + spin[k][l-1] + spin[k][l+1]) : (k==(N-1) && l==(N-1)) ? spin[k][l] * (spin[k-1][l] + spin[0][l] + spin[k][l-1] + spin[k][0]) : spin[k][l] * (spin[k-1][l] + spin[k+1][l] + spin[k][l-1] +spin[k][l+1]); exten += spin[k][l]; } } printf("test2"); coupen *= -J/2; exten *= B; energy = coupen + exten; // Flipping for(m=1;m==end;m++) { for(n=1;n==N*N;n++) /* Flip attempts withing one sweep */ { // Get random numbers srand48((unsigned int) time(NULL)); k = (int) N * drand48(); /* (int) cast acts as ceiling function! */ l = (int) N * drand48(); z = drand48(); dspin = (double) - 2 * spin[k][l]; dcoupen += (k==0 && l==0) ? dspin * (spin[(N-1)][l] + spin[k+1][l] + spin[k][(N-1)] +spin[k][l+1]) : (k==0 && l!=0 && l!=(N-1)) ? dspin * (spin[(N-1)][l] + spin[k+1][l] + spin[k][l-1] +spin[k][l+1]) : (k=0 && l==(N-1)) ? dspin * (spin[(N-1)][l] + spin[k+1][l] + spin[k][l-1] +spin[k][0]) : (k!=0 && k!=(N-1) && l==0) ? dspin * (spin[k-1][l] + spin[k+1][l] + spin[k][(N-1)] +spin[k][l+1]) : (k=(N-1) && l==0) ? dspin * (spin[k-1][l] + spin[0][l] + spin[k][(N-1)] +spin[k][l+1]) : (k!=0 && k!=(N-1) && l==(N-1)) ? dspin * (spin[k-1][l] + spin[k+1][l] + spin[k][l-1] +spin[k][0]) : (k==(N-1) && l!=0 && l!=(N-1)) ? dspin * (spin[k-1][l] + spin[0][l] + spin[k][l-1] +spin[k][l+1]) : (k==(N-1) && l==(N-1)) ? dspin * (spin[k-1][l] + spin[0][l] + spin[k][l-1] +spin[k][0]) : dspin * (spin[k-1][l] + spin[k+1][l] + spin[k][l-1] +spin[k][l+1]); dcoupen *= -J; dexten = dspin * B; dE = dcoupen + dexten; r = exp(dE); // Only if r>z perform the flip if(r>z) { spin[k][l] = -spin[k][l]; } // Print configuration to screen after each sweep, as + and - for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { if(spin[i][j]==1) printf("+"); if(spin[i][j]==-1) printf("-"); } printf("/n"); } } // Calculate M and CM and save them to file if number of sweeps is higher than a certain value if(m>50) { for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { M += spin[i][j]; } } CM = CM + M; fprintf(fout, "M\t\tCM\n"); fprintf(fout, "%lf\t%lf\n", M, CM); } } fclose(fout); exit(0); }
-
Bist du sicher, daß nichts passiert? Oder schließt sich das Konsolenfenster nur so schnell, daß du von den Ausgaben nichts mehr mitbekommst? (im letzteren Fall hilft die Konsolen-FAQ - "automatisches Schließen verhindern")
Außerdem sind die Schleifenbedingungen in Zeile 87 und 89 falsch - die Bedingung 'm==end' ist bereits bei der ersten Überprüfung nicht erfüllt und die Schleife wird sofort abgebrochen.
-
Vielen Dank fuer die sehr schnelle Antwort!
Stimmt die Schleife war falsch! Vielen Dank fuer den guten Hinweis! Leider loest es das Problem nicht, denn das eigentliche Problem muss etwas grundlegenderes sein da das Program ueberhaupt nicht ausgefuerht wird.
Es wird tatsaechlich nicht ausgefuerht, das Konsolenfenster schliesst sich nicht (ich benutze Ubuntu Linux und hab das terminal window die ganze Zeit ueber offen).
Danke!
-
Wie hast du denn das Programm gestartet?
(btw, die Tatsache, daß deine Datei angelegt wird, deutet darauf hin, daß es tatsächlich gestartet wurde)
-
Kompilation mit
gcc -o main main.c -lm
ALLES OK - keine Fehler!
dann (da ich die Kommandozeileneingabe fuers degubben entfernt hab) im richtigen Verzeichnis
./main
(nichts passiert - aber Program startet und legt Datei an, CPU wird warm und Prog laeuft, macht aber nichts...evtl loop der nicht terminiert - hab aber alle mehrfach gecheckt..?
Danke!
-
Kannst du mal die printf(...) Aufrufe zur Debug-Verfolgung ersetzen durch fprintf(stderr,...). Und bau auch einige Überwachungsausgaben im Inneren der Schleifen ein, um zu sehen, wo es Probleme gibt.
PS: Was mir aufgefallen ist, als ich nach möglichen Fehlern in der Schleife gesucht habe:
- deine Code-Einrückung ist miserabel (und bei längeren Verbund-Anweisungen kann es nicht schaden, am Ende einen Kommentar anzuhängen, wohin die } Klammer gehört)
- srand() benötigst du nur einmal am Programmanfang und nicht bei jedem Schleifendurchlauf
- die coupen+=... Anweisung ist schon fast ein Fall für den Obfuscated C Contest - und dort drin hast du einige Male Zuweisung und Vergleich durcheinandergebracht (z.B. am Anfang von Zeile 69) - damit zerlegst du dir effektiv die Zählvariable deiner Schleife.
-
Netter Bug:
Du hast in der Schleife bei "coupen += ..." an einigen Stellen nicht die Schleifenvariablen abgefragt, sondern setzt sie immer wieder:
(k=0 && ...) // <- falsch (k==0 && ...) // <- richtig
Und dies mehrfach und weiter unten bei 'flipping' auch (C&P-Fehler?).
Gibt dein Compiler keine Warnungen aus? Sonst schalte mal alle Warnungen ein (-w-all oder so ähnlich).
-
Hi,
deine Ausgaben siehst du nicht weil du keine Zeilenumbrüche hast und somit nie
stdout geflusht wird.
Mach mal am Ende jedes printf ein \n, zB printf("hello\n");mfg exnase
-
Th schrieb:
Netter Bug:
Du hast in der Schleife bei "coupen += ..." an einigen Stellen nicht die Schleifenvariablen abgefragt, sondern setzt sie immer wieder:
(k=0 && ...) // <- falsch (k==0 && ...) // <- richtig
Und dies mehrfach und weiter unten bei 'flipping' auch (C&P-Fehler?).
Gibt dein Compiler keine Warnungen aus? Sonst schalte mal alle Warnungen ein (-w-all oder so ähnlich).
AHA! Ja das war der entscheidene Bug, alles andere sollte jetzt schnell zu debuggen sein! Vielen, vielen Dank fuer diesen Tipp!!!! Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!
Juhu!Herzlichen Dank fuer die Hilfe aller Beteiligter!
PS. -Wall war auch ein sehr guter Tipp uebrigens! Haette ich auch vorher dran denken sollen...
PPS. Werd Annotationen einfuegen worauf die Klammern sich beziehen obwohl ich nicht finde, dass die Einrueckungen miserabel sind..
PPS. ^^ \n stimmt auch! Danke!
-
Hallo,
ein weitere Fehler ist die Bedingung der for-Schleife in Zeile 91
for(m=1;m==end;m++)
Schon für m==1 ist die Bedingung nicht erfüllt: 1==500?
Ich nehme mal an, es sollte
for (m=1; m<=500; ++m)
heißen.
Gruß mcr
-
So ein Blitzmerker
den Fehler hatte ich schon in der ersten Anwort erwähnt
-
CStoll schrieb:
So ein Blitzmerker
den Fehler hatte ich schon in der ersten Anwort erwähnt
Stimmt, sorry.
Hatte ich überlesen.
@edit: Aber es ist schon schwer, die richtigen Zeilennummer zu zitieren.
-
Hallo,
mir hat dieser Block coupen += () ? .. : ..; nicht gefallen. Dabei ist
mir aufgefallen, dass man es wie folgt kürzen kann:coupen += spin[k][l] * (spin[(k+N-1)%N][l] + spin[(k+1)%N][l] + spin[k][(l+N-1)%N] + spin[k][(l+1)%N]);
Ebenso die Zeile dcoupen += ...;
Gruß mcr
-
mcr schrieb:
Hallo,
ein weitere Fehler ist die Bedingung der for-Schleife in Zeile 91
for(m=1;m==end;m++)
Schon für m==1 ist die Bedingung nicht erfüllt: 1==500?
Ich nehme mal an, es sollte
for (m=1; m<=500; ++m)
heißen.
Gruß mcr
Vielen Dank fuer den Hinweis! Den Fehler hatte ich allerdings zwischendurch schon korrigiert nach Hinweis von CStoll
...trotzdem natuerlich vielen Dank!
-
duck schrieb:
Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!
Ist wohl gut so, denn ich trinke keinen Alkohol!
-
Th schrieb:
duck schrieb:
Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!
Ist wohl gut so, denn ich trinke keinen Alkohol!
hehe nagut dann eben einen O-Saft oder so..
-
Th schrieb:
duck schrieb:
Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!
Ist wohl gut so, denn ich trinke keinen Alkohol!
dann gib mir das bier!
-
Hallo noch einmal,
das Program scheint jetzt endlich zu funktionieren. Allerdings hab ich ein Problem mit dem array am Anfang spin[][], wenn ich 20x20 als Groess nehme funktioniert alles, aber ab 25x25 bekomme ich Berechnungsfehler und auf einmal negative Werte fuer Variablen die nicht negativ werden koennen, m z.B. Kann ich das irgendwie vermeiden indem ich dem Program mehr Speicher zuteile o.A.? Wenn ja, wie?
Vielen Dank!
Hier die aktuelle Version des Codes:
#include <stdio.h> #include <stdlib.h> #include <math.h> /* Don't forget to link the maths library when compiling the program -lm */ #include <time.h> int main(int argc, char **argv) { // Declaring variables, end: total no of sweeps, N:lattice size NxN // B and J are actually B/KT etc. int end=1000, N=20; int i, j, k, l, m=0, n; /* m: total number of sweeps, n: flip attempts within one sweep */ int mod=0, identical; int spin[20][20]; int M=0, CM=0; char setup; double B=0, J=0.4; double a, b, z; FILE *fout; double dcoupen, dexten, dE, d; double r; // Get command line input switch (argc) { case 6: sscanf(argv[5], "%d", &mod); case 5: sscanf(argv[4], "%d", &end); case 4: sscanf(argv[3], "%lf", &B); case 3: sscanf(argv[2], "%lf", &J); } printf("Syntax is: ./main file J B end mod\n"); printf("Default is: output.data 0.4 0 1000 0\n"); printf("Do you wish to set up the lattice randomly or magnetized (r/m)?(r) \n"); scanf("%s", &setup); // Setting up the lattice srand48((unsigned int) time(NULL)); /* Seed random number generator */ if(setup=='m') { for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { spin[i][j]=1; } printf("|\n"); } } else /* Default is randomized setup */ for(i=0;i<=(N-1);i++) /* Assgin a random value to each spin */ { for(j=0;j<=(N-1);j++) { do /* Do ... while as to execute the loop at least once */ { a = drand48(); b = drand48(); identical = 0; if(a>b) { spin[i][j] = 1.0; } else if(b>a) { spin[i][j] = -1.0; } else identical = 1; } while(identical==1); } } // Check whether file is accessible if(argc>=2) /* Use entered file name */ { if ((fout = fopen(argv[1], "w")) == NULL) { printf("Cannot open file '%s'\n", argv[1]); exit(1); } } else /* Otherwise use default file name */ { if ((fout = fopen("output.data", "w")) == NULL) { printf("Cannot open file 'output.data'\n"); exit(1); } } fprintf(fout, "# Sweep M\t\tCM\n"); /* # makes gnuplot ignore this line*/ // Print out initial state for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { M += spin[i][j]; } } CM += M; fprintf(fout, "%3d\t%4d\t%4d\n", m, M, CM); // Flipping for(m=1;m<=end;m++) { /* Initialises sweep loop */ for(n=1;n<=(N*N);n++) /* Flip attempts withing one sweep */ { /* Initialises flipping loop */ // Get random numbers k = (int) ceil(N * drand48()); l = (int) ceil(N * drand48()); z = drand48(); d = 2.0 * J * spin[k][l]; /* dcoupen = - 2 spin[k][l] * (-J) * sum of neighbouring spins */ dcoupen = (k==0 && l==0) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(N-1)] +spin[k][(l+1)]) : (k==0 && l!=0 && l!=(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]) : (k==0 && l==(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][0]) : (k!=0 && k!=(N-1) && l==0) ? d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(N-1)] +spin[k][(l+1)]) : (k==(N-1) && l==0) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(N-1)] +spin[k][(l+1)]) : (k!=0 && k!=(N-1) && l==(N-1)) ? d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][0]) : (k==(N-1) && l!=0 && l!=(N-1)) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(l-1)] +spin[k][(l+1)]) : (k==(N-1) && l==(N-1)) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(l-1)] +spin[k][0]) : d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]); dexten = -2.0 * B * spin[k][l]; dE = dcoupen + dexten; r = exp(dE); // Only if r>z perform the flip if(r>z) { spin[k][l] = - spin[k][l]; } } /* Closes flipping loop */ // Print configuration to screen after each sweep, as + and - for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { if(spin[i][j]==1.0) printf("+"); if(spin[i][j]==-1.0) printf("-"); } printf("|\n"); } printf("\n\n\n\n"); // Calculate M and CM and save them to file, cumulation starts after 50 sweeps M = 0; /* Reset M to 0 between flips */ for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { M += spin[i][j]; } } CM += M; fprintf(fout, "%3d\t%4d\t%4d\n", m, M, CM); } /* Closes sweep loop */ fclose(fout); return 0; }
-
mcr schrieb:
Hallo,
mir hat dieser Block coupen += () ? .. : ..; nicht gefallen. Dabei ist
mir aufgefallen, dass man es wie folgt kürzen kann:coupen += spin[k][l] * (spin[(k+N-1)%N][l] + spin[(k+1)%N][l] + spin[k][(l+N-1)%N] + spin[k][(l+1)%N]);
Ebenso die Zeile dcoupen += ...;
Gruß mcr
Hallo,
tut mir leid, ich hatte den post ganz uebersehen. Ich glaube das funktioniert leider nicht, obwohl es natuerlich sehr sehr nett waere. Fuer
(k==0 && l!=0 && l!=(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]) :
wuerde man an der ERSTEN Stelle spin[k-1][l] bekommen anstelle von spin[N-1][l], oder nicht?
Danke
-
duck schrieb:
int N=20; ... int spin[20][20]; if(setup=='m') { for(i=0;i<=(N-1);i++) { for(j=0;j<=(N-1);j++) { spin[i][j]=1; } printf("|\n"); } }
Hast du bei deiner Anpassung auch daran gedacht, N zu korrigieren? (btw, das ist ein guter Zeitpunkt, über benannte Konstanten nachzudenken)