2016-07-17 10 views
-1

Wenn Sie mein Programm ausführen, finden Sie den folgenden Code, der ein dynamisch zugewiesenes Array mit Strukturen enthält, ich stoße auf ein Problem.Warum bekomme ich einen 0xCCCCCCCC Fehler nach dem Zuweisen von Speicher für die Strings in meinem Schlag?

Schritte, den Fehler zu reproduzieren:

  • Führen Sie das Programm
  • ‚a‘ als Eingabe eingeben, so dass das Programm die erste Person auf das Array
  • Geben Sie ‚a‘ wieder als Eingabe hinzufügen so dass Sie die zweite Person auf dem Array
  • hinzufügen zuteilen den Speicher für die dynamische Zeichenfolge des Namens der zweiten Person (database[*n]->name = malloc(strlen(buffer) + 1); in newPerson() funcion)

bekomme ich folgende Fehlermeldung:

Exception thrown at 0x013D1C48 in IPHoofdstuk13_13.2.6.exe: 0xC0000005: Access violation writing location 0xCCCCCCCC.

Es ist wirklich seltsam, da diese bestimmte Code macht seinen Job, wenn ich den ersten Mann in die Liste aufnehmen, aber wenn ich einen anderen Kerl hinzufügen möchten erhalte ich die oben genannten Fehler .

Ich habe versucht, dies seit Stunden zu lösen, gibt es jemanden, der weiß, wie und vor allem warum dieser Fehler aufgetreten ist?

Der Code:

#define _CRTDBG_ALLOC_MAP 
#define MAX_BUFFER_SIZE 81 

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

typedef struct person 
{ 
    char* name; 
    char* adres; 
}person; 

/*Function prototypes*/ 
void newPerson(person **database, int *n); 
void printDatabase(const person *database, int n); 
void freeDatabase(person **database, int n); 
void bufferCheck(char string[]); 


int main(void) 
{ 
    person *database = NULL;//Array Pointer 
    int npersonen = 0; 
    bool stop = false; 

    while (!stop) 
    { 
     char c; 

     printf("Press a to add a new person\n"); 
     printf("Press p to print all the persons\n"); 
     printf("press q to quit the program\n"); 
     c = _getche(); 

     switch (c) 
     { 
     case 'a': 
      newPerson(&database, &npersonen); 
      break; 

     case 'p': 
      printDatabase(database, npersonen); 
      break; 

     case 'q': 
      stop = true; 
      break; 

     default: 
      printf("Wrong input ... \n"); 
      break; 
     } 
    } 

    freeDatabase(&database, npersonen); 

    free(database); 
    _CrtDumpMemoryLeaks(); 
    return 0; 
} 

void newPerson(person **database, int *n) 
{ 
    /* Create new array */ 
    char buffer[MAX_BUFFER_SIZE]; 
    //Create space for n + 1 persons 
    person *old = realloc(*database, (*n + 1) * sizeof(*old)); 

    if (old == NULL) 
    { 
     printf("Memory reallocation failed...\n"); 
    } 

    *database = old;//use larger array 

    /* Get name */ 
    printf("\nEnter name: "); 
    fgets(buffer, MAX_BUFFER_SIZE, stdin); 
    bufferCheck(buffer); 


    database[*n]->name = malloc(strlen(buffer) + 1); 

    if ((database)[*n]->name == NULL) 
    { 
     printf("Memory allocation failed...\n"); 
    } 

    strcpy((*database)[*n].name, buffer); 

    /* Get Adress */ 
    printf("\nEnter adress: "); 
    fgets(buffer, MAX_BUFFER_SIZE, stdin); 
    bufferCheck(buffer); 

    database[*n]->adres = malloc(strlen(buffer) + 1); 

    if ((database)[*n]->adres == NULL) 
    { 
     printf("Memory allocation failed...\n"); 
    } 

    strcpy((*database)[*n].adres, buffer); 

    /* Free old array */ 
    free(old); 

    /* Increase array length */ 
    ++(*n); 
} 

void printDatabase(const person *database, int n) 
{ 
    if (n < 1) 
     printf("List is empty\n"); 

    else 
    { 
     for (int i = 0; i < n; ++i) 
     { 
      printf("\nPerson %d: \n", i + 1); 
      printf("\t Name: %s", database[i].name); 
      printf("\t Adres: %s", database[i].adres); 
     } 
    } 
} 

void freeDatabase(person **database, int n) 
{ 
    for (int i = 0; i < n; ++i) 
    { 
     free(database[i]->name); 
     free(database[i]->adres); 
    } 
} 

void bufferCheck(char string[]) 
{ 
    for (int i = 0; string[i] != '\0'; ++i) 
    { 
     if (string[i] == '\n') 
      string[i] = '\0'; 
    } 
} 
+1

'(* database) [* n] .name' statt' database [* n] -> name' in 'newPerson()' (und anderswo, wenn als 'person ** 'übergeben) – Dmitri

+0

und' frei (alt); 'ist falsch. – BLUEPIXY

Antwort

2

Sie haben eine Reihe von person zugeordnet, zugänglich von main() durch ein person * zur ersten Struktur in der Anordnung. Sie übergeben es als person ** an andere Funktionen, damit Sie die Adresse des Arrays ändern können. Das ist in Ordnung ... aber Sie versuchen dann, auf Elemente des Arrays zuzugreifen, ohne richtig zu deneferenzieren.

In den Funktionen, die Sie person **database übergeben haben, müssen Sie auf die Strukturen des Arrays zugreifen, indem Sie zunächst database den tatsächlichen Zeigerwert (die Adresse die Variable in Haupt hält) abrufen, dann indizieren Sie den Zeiger, um bei der struct Sie wollen - so müssen Sie (*database)[*n], um die Struktur zu erhalten, anstatt zu versuchen, database[*n] zu verwenden, um einen Zeiger darauf zu bekommen (was nicht funktioniert, weil der Zeiger, den Sie indizieren, auf den Zeiger in main() zeigt und nicht zu dem Array, das Sie zugewiesen haben).

So zum Beispiel in newPerson(), die Zeile:

database[*n]->name = malloc(strlen(buffer) + 1); 

... würde:

(*database)[*n].name = malloc(strlen(buffer) + 1); 

... und andere Ereignisse würden in ähnlicher Weise ändern.


Und als @BLUEPIXY kommentiert, nicht frei old nach realloc() das Array ing, sind da Sie immer noch den Block verweist er auf verwenden.

+0

Vielen Dank für die Erklärung, was ich falsch gemacht habe und was ich ändern sollte. Die Funktion funktioniert jetzt einwandfrei. Mit deiner Erklärung war ich auch in der Lage, meine freie Funktion für diese dynamischen Saiten innerhalb von 2 Sekunden zu debuggen. Das Programm funktioniert jetzt, danke! – AggonyAchilles

+1

Ihre 'freeDatabase' wird sich ebenfalls ändern, z. 'free ((* Datenbank) [i] .name);' –

0

Die Linie

database[*n]->name = malloc(strlen(buffer) + 1); 

scheint nicht richtig. Es sollte sein:

old[*n]->name = malloc(strlen(buffer) + 1); 
+0

Hey @RSahu Ihre Lösung hat auch funktioniert, vielen Dank! – AggonyAchilles