[C] Speicherzugriffsfehler

Hallo,
ich habe seit ca. einer Woche ein Problem mit einem Speicherzugriffsfehler. Ich habe ein Testprogramm zur Lösung eines Sudokus geschrieben, das aber immer nach einem Speicherzugriffsehler abgebrochen wird. Der Fehler tritt immer an der gleichen Stelle auf, ich kann ihn dennoch nicht beheben. Beim Kompilieren mit gcc -g und anschließendem Ausführen wird zwar ein Speicherabzug geschrieben, der jedoch nur core und nicht rechnertest_test.core heißt, aber das nur am Rande. gdb weiß auch nicht, wo der Speicherzugriffsfehler stattfindet, er gibt nur aus:
Code:
Program received signal SIGSEGV, Segmentation fault.
0x000000000000000e in ?? ()
Wie kann ich den Fehler beheben? Anbei mein Code:
Code:
#include <stdio.h>
#include <stdlib.h>

int position[82]; 

int pruefe_quadrat_eins;
int pruefe_quadrat_zwei;
int pruefe_quadrat_drei;
int var = 1;
int *d = &var;
int i = 0; /* Allzweckvariable */
int zeile = 1; /* Die laufende Zeilennummer */
int zelle = 1; /* Die laufende Zellennummer, die gerade überprüft wird */
int nicht_gefunden_zeile[10]; /* Die Zeile von nicht gefundenen Nummern */
int nicht_gefunden_nummer[82]; /* Nicht gefundene Nummern */
int fehlt_nicht[10]; /* Die Nummern, die in dieser Zeile fehlen */

int berechne();
int zeichneFeldNeu();
int suche_nummer(int nummer, int zeile);
int suche_quadrat(int anfang, int nummer);
int suche_spalte(int anfang, int nummer);
int suche_nach_fehlendem(int d);

int main(int argc, char *argv[])
{
    position[1] = 0;
    position[2] = 1;
    position[3] = 0;
    position[4] = 0;
    position[5] = 0;
    position[6] = 0;
    position[7] = 6;
    position[8] = 0;
    position[9] = 0;
    position[10] = 7;
    position[11] = 8;
    position[12] = 0;
    position[13] = 0;
    position[14] = 0;
    position[15] = 0;
    position[16] = 0;
    position[17] = 5;
    position[18] = 0;
    position[19] = 6;
    position[20] = 3;
    position[21] = 9;
    position[22] = 0;
    position[23] = 0;
    position[24] = 1;
    position[25] = 7;
    position[26] = 0;
    position[27] = 0;
    position[28] = 0;
    position[29] = 0;
    position[30] = 0;
    position[31] = 7;
    position[32] = 0;
    position[33] = 0;
    position[34] = 0;
    position[35] = 0;
    position[36] = 0;
    position[37] = 0;
    position[38] = 2;
    position[39] = 0;
    position[40] = 9;
    position[41] = 0;
    position[42] = 3;
    position[43] = 0;
    position[44] = 6;
    position[45] = 0;
    position[46] = 0;
    position[47] = 0;
    position[48] = 0;
    position[49] = 0;
    position[50] = 0;
    position[51] = 2;
    position[52] = 0;
    position[53] = 0;
    position[54] = 0;
    position[55] = 0;
    position[56] = 0;
    position[57] = 1;
    position[58] = 5;
    position[59] = 0;
    position[60] = 0;
    position[61] = 2;
    position[62] = 9;
    position[63] = 7;
    position[64] = 0;
    position[65] = 4;
    position[66] = 0;
    position[67] = 0;
    position[68] = 0;
    position[69] = 0;
    position[70] = 0;
    position[71] = 8;
    position[72] = 3;
    position[73] = 0;
    position[74] = 0;
    position[75] = 8;
    position[76] = 0;
    position[77] = 0;
    position[78] = 0;
    position[79] = 0;
    position[80] = 4;
    position[81] = 0;
    /* Ablauf:
     * In der Funktion berechne() werden fehlende Nummer in Zeilen ausfindig gemacht
     * Dann wird die fehlende Nummer und die Zeile der Funktion suche_nummer(int nummer, int zeile)
     * übergeben. In dieser Funktion werden jetzt die Quadrate, der Zeile untersucht. Wenn in einem der Quadrate
     * die Nummer nicht vorkam, werden die Spalten des Quadrates nach der Nummer durchsucht.
     * Sobald in einer Spalte die Nummer nicht vorkam, wird die zugehörige Zellennummer gespeichert und als
     * mögliche Stelle für die Nummer gesucht. Wenn es am Ende mehr als eine Möglichkeit gab, gibt die Funktion
     * 1 zurück. Dann wird die Zeile und die Nummer in zwei Arrays an der gleichne Stelle gespeichert und später wieder
     * versucht,
     */
    berechne();
    printf("Das Feld: \n");
    zeichneFeldNeu(); /* Das gelöste Feld neu zeichnen */
    return 0;
}

int berechne()
{
    while(i <= 9) {
        nicht_gefunden_zeile[i] = 0;
        i++;
    }
    i = 0;
    while(i <= 81) {
        nicht_gefunden_nummer[i] = 0;
        i++;
    }
    i = 0;
    while(i <= 9) {
        fehlt_nicht[i] = 0;
        i++;
    }
    int nummer_zelle[10]; /* Die Nummer, die die Zelle hat */
    /* In dieser Schleife wird jede Zeile durchsucht und wenn eine Zahl fehlt, wird suche_nummer mit dieser Zahl
     * und der Zeilennummer aufgerufen 
     */
    while(zeile <= 9) { /* Alle Zeilen durchprobieren */
        /* printf("Zu untersuchende Zeile: %i\n", zeile); */
        i = 1;
        zelle =  (zeile*9)-8; /* Die erste Zelle der Zeile */
        printf("Erste Zelle der Zeile: %i\n", zelle);
        if(zelle == 0)
            zelle = 1;
        i = 0;
        while(i <= 9) {
            nummer_zelle[i] = 0;
            i++;
        }
        i = 1; /* i wird hier dazu benutzt, den Arraywert von nummer_zelle nicht über 9 steigen zu lassen */
        while(zelle <= (zeile*9)) { /* Alle Zellen der Zeile überprüfen(zeile*9) bezeichnet die
                         * letzte Zelle der Zeile
                         */
            /* Erste Möglichkeit: Man notiert welche Nummer die Zelle hat und prüft später, 
             * welche fehlt, oder man frägt nacheinander die Nummer ab, die die Zelle haben kann .
             * Erste Möglichkeit ist besser (glaube ich)
             */
            nummer_zelle[i] = position[zelle];
            zelle++;
            i++;
        }
        /* Jetzt muss überprüft werden, was gefehlt hat */
        i = 1;
        while(i <= 9) { /* In dieser Schleife werden alle vorhandenen Zahlen geordnet in ein Array eingetragen */
            if(nummer_zelle[i] != 0)
                fehlt_nicht[i] = position[i];
            i++;
        }
        /* if(malloc(sizeof(&d)) == NULL) {
          printf("Not enough memory\n");
          return 1;
        } */ /* Dies bringt irgendwie nichts */
        printf("fehlt_nicht[1]: %i\n", fehlt_nicht[1]);
        printf("d = 1\n");
        if(fehlt_nicht[1] == 0)
            if(suche_nummer(1, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[1] = 1;
            }
        printf("fehlt_nicht[2]: %i\n", fehlt_nicht[2]);
        printf("d = 2\n");
        if(fehlt_nicht[2] == 0)
            if(suche_nummer(2, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[2] = 2;
            }
        printf("fehlt_nicht[3]: %i\n", fehlt_nicht[3]);
        printf("d = 3\n");
        if(fehlt_nicht[3] == 0)
            if(suche_nummer(3, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[3] = 3;
            }
        printf("fehlt_nicht[4]: %i\n", fehlt_nicht[4]);
        printf("d = 4\n");
        if(fehlt_nicht[4] == 0)
            if(suche_nummer(4, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[4] = 1;
            }
        printf("fehlt_nicht[5]: %i\n", fehlt_nicht[5]);
        printf("d = 5\n");
        if(fehlt_nicht[5] == 0)
            if(suche_nummer(5, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[5] = 5;
            }
        printf("fehlt_nicht[6]: %i\n", fehlt_nicht[6]);
        printf("d = 6\n");
        if(fehlt_nicht[6] == 0)
            if(suche_nummer(6, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[6] = 6;
            }
        printf("fehlt_nicht[7]: %i\n", fehlt_nicht[7]);
        printf("d = 7\n");
        if(fehlt_nicht[7] == 0)
            if(suche_nummer(7, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[7] = 7;
            }
        printf("fehlt_nicht[8]: %i\n", fehlt_nicht[8]);
        printf("d = 8\n");
        if(fehlt_nicht[8] == 0)
            if(suche_nummer(8, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[8] = 8;
            }
        printf("fehlt_nicht[9]: %i\n", fehlt_nicht[9]);
        printf("d = 9\n");
        if(fehlt_nicht[9] == 0)
            if(suche_nummer(9, zeile) != 0) {
            nicht_gefunden_zeile[zeile] = zeile;
            nicht_gefunden_nummer[9] = 9;
            }
        zeile++;
    }
    return 0;
}
    

int suche_nummer(int nummer, int zeile)
{
    printf("Nummer: %i, zeile: %i\n", nummer, zeile);
    int moeglich[10]; /* Hier werden die Moeglichkeiten protokolliert */
    int i = 0; /* Allzweckvariable */
    while(i <= 9) {
        moeglich[i] = 0;
        i++;
    }
    printf("Beginn der Überprüfung der Quadrate\n");
    /* Hier werden zuerst die Quadrate der Zeile überprüft (mithilfe der Funktion suche_quadrat) */
    if(zeile == 1 || zeile == 2 || zeile == 3) { /* Die erste Reihe der Quadrate */
        pruefe_quadrat_eins = suche_quadrat(1, nummer);
        pruefe_quadrat_zwei = suche_quadrat(4, nummer);
        pruefe_quadrat_drei = suche_quadrat(7, nummer);
        if(pruefe_quadrat_eins != 0) { /* Im ersten Quadrat kam die gesuchte Nummer nicht vor, also die Spalten
                            * untersuchen
                            */
            printf("Untersuchung der Spalten 1, 2, 3\n");
            printf("Spalte 1:\n");
            if(suche_spalte(1, nummer) != 0) {
                if(zeile == 1)
                    moeglich[1] = 1;
                else if(zeile == 2)
                    moeglich[10] = 10;
                else if(zeile == 3)
                    moeglich[19] = 19;
            }
            printf("Spalte 2:\n");
            if(suche_spalte(2, nummer) != 0) {
                if(zeile == 1)
                    moeglich[2] = 2;
                else if(zeile == 2)
                    moeglich[11] = 11;
                else if(zeile == 3)
                    moeglich[20] = 20;
            }
            printf("Spalte 3:\n");
            if(suche_spalte(3, nummer) != 0) {
                if(zeile == 1) 
                    moeglich[3] = 3;
                else if(zeile == 2)
                    moeglich[12] = 12;
                else if(zeile == 3)
                    moeglich[21] = 21;
            }
        }
        printf("Quadrat zwei:\n");
        printf("pruefe_quadrat_zwei = %i\n", pruefe_quadrat_zwei);
        if(pruefe_quadrat_zwei != 0) { /* Im zweiten Quadrat kam die gesucht Nummer nicht vor, also die Spalten
                        * untersuchen
                        */
            printf("Untersuchung der Spalten 4, 5, 6\n");
            printf("Untersuche Spalte 4\n");
            if(suche_spalte(4, nummer) != 0) {
                if(zeile == 1)
                    moeglich[4] = 4;
                else if(zeile == 2)
                    moeglich[13] = 13;
                else if(zeile == 3)
                    moeglich[22] = 22;
            }
            printf("Untersuche Spalte 5\n");
            if(suche_spalte(5, nummer) != 0) {
                if(zeile == 1)
                    moeglich[5] = 5;
                else if(zeile == 2)
                    moeglich[13] = 13;
                else if(zeile == 3)
                    moeglich[23] = 23;
            }
            printf("Untersuche Spalte 6\n");
            if(suche_spalte(6, nummer) != 0) {
                if(zeile == 1)
                    moeglich[6] = 6;
                else if(zeile == 2)
                    moeglich[14] = 14;
                else if(zeile == 3)
                    moeglich[24] = 24;
            }
        }
        if(pruefe_quadrat_drei != 0) { /* Im zweiten Quadrat kam die gesucht Nummer nicht vor, also die Spalten
                           * untersuchen 
                           */
            if(suche_spalte(7, nummer) != 0) {
                if(zeile == 1)
                    moeglich[7] = 7;
                else if(zeile == 2)
                    moeglich[15] = 15;
                else if(zeile == 3)
                    moeglich[25] = 25;
            }
            if(suche_spalte(8, nummer) != 0) {
                if(zeile == 1)
                    moeglich[8] = 8;
                else if(zeile == 2)
                    moeglich[16] = 16;
                else if(zeile == 3)
                    moeglich[26] = 26;
            }
            if(suche_spalte(9, nummer) != 0) {
                if(zeile == 1)
                    moeglich[9] = 9;
                else if(zeile == 2)
                    moeglich[17] = 17;
                else if(zeile == 3)
                    moeglich[27] = 27;
            }

        }
    }
    else if(zeile == 4 || zeile == 5 || zeile == 6) {
        pruefe_quadrat_eins = suche_quadrat(28, nummer);
        pruefe_quadrat_zwei = suche_quadrat(31, nummer);
        pruefe_quadrat_drei = suche_quadrat(34, nummer);
        if(pruefe_quadrat_eins != 0) {
            if(suche_spalte(28, nummer) != 0) {
                if(zeile == 4)
                    moeglich[28] = 28;
                else if(zeile == 5)
                    moeglich[37] = 37;
                else if(zeile == 6)
                    moeglich[46] = 46;
            }
            if(suche_spalte(29, nummer) != 0) {
                if(zeile == 4)
                    moeglich[29] = 29;
                else if(zeile == 5)
                    moeglich[38] = 38;
                else if(zeile == 6) 
                    moeglich[47] = 47;
            }
            if(suche_spalte(30, nummer) != 0) {
                if(zeile == 4)
                    moeglich[30] = 30;
                else if(zeile == 5)
                    moeglich[39] = 39;
                else if(zeile == 6)
                    moeglich[48] = 48;
            }
        }
        if(pruefe_quadrat_zwei != 0) {
            if(suche_spalte(31, nummer) != 0) {
                if(zeile == 4)
                    moeglich[31] = 31;
                else if(zeile == 5)
                    moeglich[40] = 40;
                else if(zeile == 6)
                    moeglich[49] = 49;
            }
            if(suche_spalte(32, nummer) != 0) {
                if(zeile == 4)
                    moeglich[32] = 32;
                else if(zeile == 5)
                    moeglich[41] = 41;
                else if(zeile == 6)
                    moeglich[50] = 50;
                }
            if(suche_spalte(33, nummer) != 0) {
                if(zeile == 4)
                    moeglich[33] = 33;
                else if(zeile == 5)
                    moeglich[42] = 42;
                else if(zeile == 6)
                    moeglich[51] = 51;
            }

        }
        if(pruefe_quadrat_drei != 0) {
            if(suche_spalte(34, nummer) != 0) {
                if(zeile == 4)
                    moeglich[34] = 34;
                else if(zeile == 5)
                    moeglich[43] = 43;
                else if(zeile == 6)
                    moeglich[52] = 52;
            }
            if(suche_spalte(35, nummer) != 0) {
                if(zeile == 4)
                    moeglich[35] = 8;
                else if(zeile == 5)
                    moeglich[44] = 44;
                else if(zeile == 6)
                    moeglich[53] = 53;
            }
            if(suche_spalte(36, nummer) != 0) {
                if(zeile == 4)
                    moeglich[36] = 9;
                else if(zeile == 5)
                    moeglich[45] = 45;
                else if(zeile == 6)
                    moeglich[54] = 54;
            }
        }
    }
    else if(zeile == 7 || zeile == 8 || zeile == 9) {
    pruefe_quadrat_eins = suche_quadrat(55, nummer);
    pruefe_quadrat_zwei = suche_quadrat(58, nummer);
    pruefe_quadrat_drei = suche_quadrat(61, nummer);
    if(pruefe_quadrat_eins != 0) {
        if(suche_spalte(55, nummer) != 0) {
            if(zeile == 7)
                moeglich[55] = 55;
            else if(zeile == 8)
                moeglich[64] = 64;
            else if(zeile == 9)
                moeglich[73] = 73;
        }
        if(suche_spalte(56, nummer) != 0) {
            if(zeile == 7)
                moeglich[56] = 56;
            else if(zeile == 8)
                moeglich[65] = 65;
            else if(zeile == 9)
                moeglich[74] = 74;
        }
        if(suche_spalte(57, nummer) != 0) {
            if(zeile == 7)
                moeglich[57] = 57;
            else if(zeile == 8)
                moeglich[66] = 66;
            else if(zeile == 9)
                moeglich[75] = 75;
        }
    }
    if(pruefe_quadrat_zwei != 0) {
        if(suche_spalte(58, nummer) != 0) {
          if(zeile == 7)
            moeglich[56] = 56;
        else if(zeile == 8)
            moeglich[67] = 67;
        else if(zeile == 9)
            moeglich[76] = 76;
        }
        if(suche_spalte(59, nummer) != 0) {
            if(zeile == 7)
                moeglich[59] = 59;
            else if(zeile == 8)
                moeglich[68] = 68;
            else if(zeile == 9)
                moeglich[77] = 77;
        }
        if(suche_spalte(60, nummer) != 0) {
            if(zeile == 7)
                moeglich[60] = 60;
            else if(zeile == 8)
                moeglich[69] = 69;
            else if(zeile == 9)
                moeglich[78] = 78;
        }
    }
    if(pruefe_quadrat_drei != 0) {
        if(suche_spalte(61, nummer) != 0) {
            if(zeile == 7)
                moeglich[60] = 60;
            else if(zeile == 8)
                moeglich[70] = 70;
            else if(zeile == 9)
                moeglich[79] = 79;
        }
        if(suche_spalte(62, nummer) != 0) {
            if(zeile == 7)
                moeglich[62] = 62;
            else if(zeile == 8)
                moeglich[71] = 71;
            else if(zeile == 9)
                moeglich[80] = 80;
        }
        if(suche_spalte(63, nummer) != 0) {
            if(zeile == 7)
                moeglich[63] = 63;
            else if(zeile == 8)
                moeglich[72] = 72;
            else if(zeile == 9)
                moeglich[81] = 81;
        }
    }
    }
    
    /* Jetzt prüfen, wie viele Möglichkeiten es gab */
    i = 1;
    int zaehle = 0; /* Zählt mit, wie viele Möglichkeiten es gibt */
    while(i <= 81) {
        if(moeglich[i] != 0)
            zaehle++;
        i++;
    }
    if(zaehle >= 2)
        return 1;
    else {
        i = 1;
        while(i <= 81) {
            if(moeglich[i] != 0) {
                printf("Position %i bekommt den Wert %i\n", i, nummer);
                position[i] = nummer;
            }
            i++;
        }
    }
    return 0;
}

int suche_quadrat(int anfang, int nummer) /* Anfang bezeichnet den Anfang des Quadrates, nummer bezcinet die Nummer,
                       * nach der gesucht werden soll
                       */
{
    int i = anfang; /* i wird für die Schleife benötigt */
    int ende = anfang+20; /* Gibt das Ende des Quadrates an */
    /* Nun wird das Quadrat nach nummer abgesucht */
    while(i <= ende+1) { /* Ende+1, um später besser prüfen zu können */
        if(position[i] == nummer)
            break;
        if(i == anfang+2 || i == anfang+11)
            i = i+3;
        else {
            i++;
        }
        if(i == ende+1)
            break;
    }
    if(i == ende+1)
        return 0;
    return 1;
}

int suche_spalte(int anfang, int nummer) /* Anfang bezeichnet den Anfang der Spalte, nummer bezeichnet die Nummer,
                      * nach der gesucht werden soll
                      */
{
    int i = anfang; /* i wird für die Schleife benötigt */
    int ende = anfang+72; /* Ende der Spalte */
    /* Nun wird die Spalte nach nummer abgesucht */
    while(i <= ende+1) { /* ende+1, um später besser prüfen zu können */
        if(position[i] == nummer)
            break;
        if(i == anfang+72) {
            i++;
            break;
        }
        i = i+9;
    }
    if(i == ende+1)
        return 0;
    return 1;
}

int zeichneFeldNeu()
{
    int zeile = 1; /* Gibt die Zeile an, die gerade gezeichnet wird */
    int zelle = 1; /* Gibt die Zelle an, die gerade gezeichnet wird */
    int ende; /* Gibt das Ende der Zeile an */
    while(zeile <= 9) {
        ende = zeile*9;
        while(zelle <= ende) {
            printf("|%i|", position[zelle]);
            zelle++;
        }
        printf("\n");
        zeile++;
    }
    return 0;
}
PS: Die printf()-Aufrufe sind meistens zum Mitverfolgen des Programms da, da der Debugger ja anscheinend versagt hat:rolleyes:
 
Du zerschießt dir den Stack, weil du in suche_nummer() bei fast jeder Gelegenheit über die Grenzen von deinem Array moeglich hinaus schreibst. Weil der Stack dann total zerschossen ist, kann gdb dir auch einen backtrace mehr anzeigen.
 
Ok, danke, so ein beknackter Anfängerfehler:rolleyes: Weiß auch nicht, warum mir das nie aufgefallen ist. Werd's mal versuchen. Eine Woche grübeln... Aber naja, danke für den Tipp, das passiert mir jetzt glaube ich nie mehr:thumb_up:
 
Zurück
Oben