2016-05-31 7 views
0

Ich habe zwei Funktionen open_files und read_bytes. Wenn ich nur open_files anrufe, funktioniert alles wie es sollte, aber wenn ich read_bytes nachher rufe, erhalte ich einen Segmentierungsfehler in open_files. Ich benutze gcc als Compiler.Segmentaion Fehler bei Speicherzuweisung

open_files ist eine Funktion, die durch ein Verzeichnis sucht und eine Struktur mit dem Dateinamen und der Länge des char-Arrays füllt.

read_bytes ist eine Funktion ohne Code und gibt nur 1.

Die Struktur für Dateinamen

struct file_name{ 
    char * name; 
    int length; 
}; 

Die Hauptfunktion:

int main(int argc, char **argv){ 
    struct file_name ** files; 
    int file_length; 
    unsigned char * hex; 
    long int bytesLength; 
    printf("CRAP"); 
    getchar(); 
    //Function open_files works if read_bytes function is not called.... 
    if(open_files(files, &file_length) >= 0){ 
     printf("CRAP2"); 
     getchar(); 
     if (read_bytes(hex, &bytesLength, files[0]->name) >= 0){ 
      for(int i = 0; i < bytesLength; ++i){ 
       printf("%X\n",hex[i]); 
      } 
     } 
    } 
    else{ 
     printf("Something went wrong"); 
    } 

    printf("%s\n", "Helluuuuuu"); 

    free_memory(files, file_length); 

    return 0; 
} 

Die open_files Funktion eine datei_name Struktur schafft für jede Datei in einem Verzeichnis.

int open_files(struct file_name ** files, unsigned int * length){ 
    DIR * dir; 
    struct dirent * ent; 
    int count = 0; 
    if((dir = opendir("TestFiles")) != NULL){ 

     while((ent = readdir(dir)) != NULL){ 
      ++count; 

     } 
     count -= 2; 
     closedir(dir); 
    } 
    else{ 
     //Couldn't open directory 
     perror(""); 
     return -1; 
    } 
    printf("working"); 
    getchar(); 
    //Allocate memory 
    *files = malloc(count * sizeof(struct file_name *)); 
    printf("not working"); 
    getchar(); 
    *length = count; 

    if((dir = opendir("TestFiles")) != NULL){ 
     count = 0; 
     while((ent = readdir(dir)) != NULL){ 
      if(strcmp(ent->d_name,".") != 0 && strcmp(ent->d_name,"..") != 0){ 
       struct file_name * file = malloc(sizeof(struct file_name)); 
       file->name = malloc(strlen(ent->d_name)); 
       strcpy(file->name,ent->d_name); 
       file->length = strlen(ent->d_name); 
       files[count] = file; 
       ++count; 
      } 
     } 
     closedir(dir); 
    } 
    else{ 
     //Couldn't open directory 
     perror(""); 
     return -1; 
    } 

    return 0; 
} 

Die read_bytes ist eine leere Funktion, die 1 zurückgibt:

int read_bytes(unsigned char * hex, long int * length, char * file){ 
    //FILE * fp; 
    //*length = file_size(file); 
    //printf("%li\n",*length); 

    //fp = fopen("TestFiles/first.jpg", "r"); 
    //fread(hex, 1, *length, fp); 
    //fclose(fp); 

    return 1; 
} 
+2

'file-> name = malloc (strlen (ent-> d_name));' -> 'file-> name = malloc (strlen (ent-> d_name) +1); '(+1) Vielleicht auch andere Probleme. – chux

+0

BytesLength enthält Müll so weit ich denke. Sie speichern keinen Wert und übergeben ihn an for loop. – Mazhar

+0

@chux Ich habe +1 und immer noch Segmentierungsfehler hinzugefügt – Olof

Antwort

2

Sie haben

*files = malloc(count * sizeof(struct file_name *)); 

Ihr Zeigerfeld zuzuordnen, die nicht korrekt ist. Ein Array von struct Zeiger würde Typ struct file_name ** aber sie weisen es einen struct file_name * ·

Dann tun Sie:

files[count] = file; 

Für count == 0, dass die Adresse von malloc() (files[0] == *files), für count > 0 zurücküberschreibt er ruft undefiniert Verhalten.

Sie entweder ein struct file_name ***-open_files() passieren könnte und

files[count] = file; 

zu

(*files)[count] = file; 

oder ein Array von Strukturen zuweisen ändern:

*files = malloc(count * sizeof(struct file_name)); 
.... 
     if(strcmp(ent->d_name,".") != 0 && strcmp(ent->d_name,"..") != 0){ 
      struct file_name * file = (*files) + count; // struct is already allocated (alternatively: &((*files)[count]) 
      file->name = malloc(strlen(ent->d_name)+1); 
      strcpy(file->name,ent->d_name); 
      file->length = strlen(ent->d_name); 
      ++count; 
     } 

In main(), müssen Sie &files passieren zu open_files() in beiden Fällen. Wenn Sie die zweite Lösung wählen, bitte

struct file_name ** files; 

zu

struct file_name * files; 
files[0]->nam 

zu

files[0].name 

Bitte beachten Sie file->name = malloc(strlen(ent->d_name)+1);

und

ändern, die nec ist in beiden Fällen wie bereits erwähnt

+0

.. und in 'main()' do 'struct Dateiname * Dateien; .... open_files (& files, ... '. – alk

+1

@alk hast du natürlich Recht, ich habe mir nur die Funktion selbst angeschaut. Hinzugefügt, danke –

+0

@IngoLeonhardt In der Zeile' struct Dateiname * Datei = & Dateien [count]; // struct ist bereits vergeben 'Ich bekomme a:' warning: Initialisierung vom inkompatiblen Zeigertyp [-Wincompatible-pointer-types] struct dateiname * file = & files [count]; // struct ist schon' – Olof