C Zugriff auf zweidimensionales char-Array

Zerstoerer

Lieutenant
Registriert
Okt. 2010
Beiträge
685
Hallo zusammen,

als Lernprojekt bin ich gerade dabei ein kleines Verschlüsselungsprogramm zu schreiben. Kern ist dabei ein zweidimensionales char-Array, in dem verschiedene Elemente gespeichert sind, und die ich im Verlauf immer wieder aufrufen muss.
Dabei ist das Array in einem Struct durch
Code:
char** table;
im Header definiert. Ich greife von einer meiner Methoden nun normal per
Code:
Struct->table[x][y]
darauf zu.
Mein Problem ist nun, dass alles eine bestimmte Zeit funktioniert und ich nach einer bestimmten Iteration keinen Zugriff mehr auf das Array bekomme. Wenn ich das Programm mit Codeblocks ausführe, schaffe ich 30 Durchläufe, mit Visual Studio z.B. nur 8 Durchläufe. Ich führe dabei nur eine einfache for-Schleife aus, es wird nix verändert, doch jeweils nach einer bestimmten Iteration verliefere ich immer den Zugriff.
Hat von euch vielleicht einer eine Idee, woran das liegen könnte?

Wäre dankbar für ein paar Tipps.
 
In Codeblocks erhalte ich den Fehler "Program received signal SIGSEGV, Segmentation fault.", in Visual Studio erhalte ich den Fehler "Zugriffsverletzung beim Lesen an Position 0xFFEE0107".
 
Ja genau das ist Segmentation fault oder kurz segfault :)
Den zu debuggen ist ohne den ganzen Code zu kennen schwierig.
 
Zuletzt bearbeitet:
Der einfachste Fall wäre, dass du auf einen Bereich außerhalb deiner Array-Größe zugreifst.
Aber wie aroxx schon sagte: Sehr schwer bis unmöglich ohne Quellcode da was herauszufinden
 
Wodurch wird denn dieser Fehler genau hervorgerufen bzw. was kann es alles für Ursachen geben? Mein Ziel wäre es natürlich, dies selber zu debuggen. Ich wundere mich halt, dass wenn ich den Code debugge, dass ich in der letzten funktionierenden Iteration die Stelle der nächsten Iteration im Array normal anzeigen lassen kann, und danach nicht mehr.
In Visual Studio habe ich auch dann gar keinen Zugriff auf jedes Element im Array mehr. Woran kann es sonst noch liegen, dass VS und CB jeweils unterschiedlich lange laufen?
 
Ein bisschen mehr Code wäre hilfreich, vor allem wie du das Array erzeugst und mehr vom Zugriff.

Generell würde ich auf mehrdimensionale Arrays verzichten und lieber nur mit eindimensionalen Arrays arbeiten. Solange es eine rechteckige Matrix kannst du den Zugriff mit einer einfachen Funktion ähnlich komfortable machen.

[Edit]
Segfaults können viele Ursachen habe. Schlussendlich heißt es aber immer, dass du auf eine ungültige Speicheradresse zugreifst, z.B. wenn du einem Zeiger folgst, der nicht initialisiert wurde oder mittlerweile ungültig ist. Es gibt aber noch viele andere Möglichkeiten.
 
Zuletzt bearbeitet:
Compiler sind unterschiedlich.
Der Fehler kommt daher, dass du auf einen Speicherbereich zugreifst, der dir nicht gehört. An was es genau liegt kannst nur du rausfinden, oder du lädst den Code hier rein
 
dass die unterschiedlich lange laufen liegt daran dass visual studio und codeblocks verschiedene compiler verwenden. d.h. die Speicherbelegung für die Elemente deines Programms ist geringfügig anders.
Einen Segfault gibt es in C nur, wenn du versuchst auf Speicher zuzugreifen, der dir nicht gehört. Soll heißen: Irgendwo im Speicher liegen deine ganzen Variablen und Arrays nacheinander:

int a = 5;
int b [6];
int c = 7

Wenn du jetzt weiter als b[5] gehst, bekommst du noch keinen segfault, sondern du überschreibst den inhalt von dem int c.
Du gehst erst kaputt, wenn du noch weiter gehst und du auf Speicher zugreifen möchtest, der einem anderen Programm gehört.
 
Hallo,
was wir hier machen ist im dunkeln zu stochern. Wenn du eine Lösung willst, dann poste bitte deinen Code. Wenn du keine möchtest, ist das Forum der falsche Anlaufpunkt. Dann wäre Google die bessere Lösung.

greetz
hroessler
 
Joa, zumindest wo/wie/wann der Speicher für table allokiert wird, wäre interessant ;D
 
vielleicht ist das hier schon das problem:
Code:
char** table;
allokiert keinen speicher.
 
Die Zeile sagt erst mal nicht viel aus, da sie Teil eines structs ist. Allerdings vermute ich auch, dass es an der Allokierung liegt, entweder überhaupt nicht oder nicht korrekt (z.B. Allokierung von Speicher für die Zeiger, aber nicht für die eigentlichen Werte).
 
habe mich halt im Kaffeesatzlesen versucht... gab leider nicht mehr informationen :D
 
Wenn ich später Zeit habe, werde ich den Code mal hochladen.
 
So, hier endlich mein Code:

Meine Header Datei:
Code:
#ifndef __ADAPTIVE_MIRROR_FIELD_H__
#define __ADAPTIVE_MIRROR_FIELD_H__

#include <inttypes.h>

typedef struct {

        uint32_t rows;

        uint32_t columns;

        char** grid;

        char* border;
} mirror_field_t;

int init_mirror_field(mirror_field_t* mf, uint32_t rows, uint32_t columns, char* border);

int load_grid_from_file(mirror_field_t* mf, char* file_name);

char mirror_symbol(mirror_field_t* mf, char input);

int mirror_symbol_stream(mirror_field_t* mf, char* input, uint32_t length, char* output);

#endif

Und meine Hauptdatei:

Code:
#include "adaptive_mirror_field.h"

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>


int init_mirror_field(mirror_field_t* mf, uint32_t rows, uint32_t columns, char* border)
{
        mf->rows = rows;
        mf->columns = columns;
        mf->grid = (char**) malloc(rows * sizeof(char*));
        for (uint32_t row = 0; row  < rows; row++) {
                mf->grid[row] = (char*) malloc(columns * sizeof(char));
                memset(mf->grid[row], ' ', columns);
        }
        mf->border = (char*) malloc(2*(mf->rows + mf->columns) * sizeof(char));
        memcpy(mf->border, border, 2*(mf->rows + mf->columns));
        return 0;
}

int load_mirror_field_grid_from_file(mirror_field_t* mf, char* file_name)
{
        FILE *file;
        file = fopen(file_name,"r");
        if(file) {
            for(int i = 0; i < 13; i++) {
                for(int j = 0; j < 13; j++) {
                    mf->grid[i][j] = fgetc(file);
                }
                fgetc(file);
            }
            fclose(file);
        } else {
            return 1;
        }
        return 0;
}

char mirror_symbol(mirror_field_t* mf, char input)
{
        int stelle = 0;
        while(mf->border[stelle] != input) {
            stelle++;
        }
        int r[2] = {0,0};
        int pos[2] = {0,0};
        if(stelle >= 39) {
            pos[0] = (stelle-51)*(-1);
            pos[1] = 0;
            r[0] = 0;
            r[1] = 1;
        } else if(stelle >= 26) {
            pos[0] = 12;
            pos[1] = (stelle - 38)*(-1);
            r[0] = -1;
            r[1] = 0;
        } else if(stelle >= 13) {
            pos[0] = stelle - 13;
            pos[1] = 12;
            r[0] = 0;
            r[1] = -1;
        } else if(stelle >= 0) {
            pos[0] = 0;
            pos[1] = stelle;
            r[0] = 1;
            r[1] = 0;
        }
        while(pos[0] >= 0 && pos[1] >= 0 && pos[0] <= 12 && pos[1] <= 12) {
                if(mf->grid[pos[0]][pos[1]] == '/') {
                    if(r[1] == -1 || r[1] == 1) {
                        r[0] = r[1]*(-1);
                        r[1] = 0;
                    } else if(r[0] == -1 || r[0] == 1) {
                        r[1] = r[0]*(-1);
                        r[0] = 0;
                    }
                } else if(mf->grid[pos[0]][pos[1]] == '\\') {
                    if(r[1] == -1 || r[1] == 1) {
                        r[0] = r[1];
                        r[1] = 0;
                    } else if(r[0] == -1 || r[0] == 1) {
                        r[1] = r[0];
                        r[0] = 0;
                    }
                }
                pos[0] += r[0];
                pos[1] += r[1];
        }
        if(pos[0] < 0) {
            return mf->border[pos[1]];
        } else if(pos[1] > 12) {
            return mf->border[13+pos[0]];
        } else if(pos[0] > 12) {
            return mf->border[(pos[1]-38)*(-1)];
        } else if(pos[1] < 0) {
            return mf->border[(pos[0]-51)*(-1)];
        }
}

int mirror_symbol_stream(mirror_field_t* mf, char* input, uint32_t length, char* output)
{
        for(int i = 0; i < length;i++) {
            const char c = mirror_symbol(&*mf,input[i]);
            strcat(output,&c);
            printf("Der %d. Buchstabe ist ein: %c\n",i,c);
        }
        return 0;
}

int main()
{
        char* alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/";
        mirror_field_t mf;
        init_mirror_field(&mf, 13, 13, alphabet);
        load_mirror_field_grid_from_file(&mf, "../data/key.txt");
        char result[16] = {0};
        char input[16] = "Testenwiresmalso";
        mirror_symbol_stream(&mf,input,16,result);
        printf("Ergebnis: %s",result);
}

Mein Fehler ist dabei immer in Zeile 71 zu beobachten, und hängt sich dort immer wieder auf. Dabei kommt der Fehler diesmal in der 13. Iteration und ich verliere den Zugriff.
 
Deine Funktion kann nicht wissen, wie groß die Felder der referenzierten Daten sind. Benutze ein lineares Array.
 
Das hilft mir jetzt leider nicht den Fehler zu finden. Klar kann die Funktion das nicht wissen, aber die Größe sollte ja immer konstant bleiben.

Edit: Ok, habs nun nach langen probieren endlich hinbekommen. Mein Problem lag in der Methode mirror_symbol_stream(...). Wo der Fehler bei der Lösung oben genau liegt, kann ich leider nicht sagen, allerdings habe ich es eben einfach mal auf die einfachste Weise probiert:
Code:
int mirror_symbol_stream(mirror_field_t* mf, char* input, uint32_t length, char* output)
{
        for(int i = 0; i < length; i++) {
            output[i] = mirror_symbol(&*mf,input[i]);
        }
        return 0;
}
Und siehe da: Es funktioniert ohne Probleme. :D

Der Tread kann also geschlossen werden.
 
Zuletzt bearbeitet:
Zurück
Oben