2016-10-21 3 views
-2

Ich habe Probleme beim Löschen aller Einträge in einer definierten Struktur. Hier ist der Funktionscode für einen einzelnen Eintrag Löschen und mein Versuch, eine Funktion „alle löschen“Löschen aller Struktureinträge in C Programmierung

typedef struct person    //Structure Set up 
{ 
    char fname[20]; 
    char lname[20]; 
    char number[20]; 
} person; 

void delInfo(int num_entries,person*contacts) 
{ 
    char delfirst[20];  //Setting up Arrays to match entry 
    char dellast[20]; 
    printf("\n First Name: "); 
    scanf("%s",delfirst); 
    printf(" Last Name: "); 
    scanf("%s",dellast); 
    int i=0; 
    for (i=0; i<num_entries; i++)  //Going through contacts 
    { 
     if (strcmp(delfirst,contacts[i].fname)==0 && strcmp(dellast,contacts[i].lname)==0)  //Testing for match between entry and contacts 
     { 
      for (i=i; i<num_entries-1; i++)   //Shifting every contact AFTER match down one 
      { 
       contacts[i]=contacts[i+1]; 
      } 
      if(num_entries !=0) 
       contacts=(person*)realloc(contacts,sizeof(person)*(num_entries-1)); //Freeing memory at end by way of realloc 
      printf("\n %s %s deleted from contacts\n\n",delfirst,dellast); 
      break; 
     } 
    } 
    if(i == num_entries) 
    { 
     printf("\n Entry Not Found\n"); 
    } 
    system("pause"); 
} 

void deleteall(int num_entries,person*contacts)   //deleting all function 
{ 
int i,j; 
    for(i=0;i<num_entries;i++){ 
     contacts[i].fname=NULL; 
    contacts[i].lname=NULL; 
     contacts[i].number=NULL; 
    } 
free(contacts); 

    printf("\n All contacts deleted\n\n"); 
    system("pause"); 
} 

Das Problem ist, dass sie inkompatible Typen sind (versuchen, Array von Leere zuweisen). Kann ich einfach eine Art Schleife verwenden und realloc verwenden, um das Array auf 0 zu verkürzen? Ich bin mir nicht sicher, wie ich alle Einträge löschen soll.

Antwort

1

Die Mitglieder des struct person sind eine feste Größe und sind nicht getrennt von der struct Instanz zugewiesen - kurze Antwort ist, dass Sie nicht die Arrays der Größe verändern können, noch können Sie freigeben ihre Lagerung ohne die gesamte struct Instanz Aufheben der Zuordnung. Die absolute Beste, was Sie in diesem Fall tun können, ist eine leere Zeichenfolge an jedes Mitglied zu schreiben es nicht in Gebrauch ist, um anzuzeigen:

strcpy(contacts[i].fname, ""); 

Dies ändert nicht die Größe des Arrays ändern, though.

Um die Mitglieder von struct person resizierbar und/oder löschbar zu machen, müssen Sie sie separat von der struct Instanz selbst zuweisen. Um das zu tun, müssen Sie sie als Zeiger zu char erklären, im Gegensatz zu Anordnungen von char:

struct person 
{ 
    char *fname; 
    char *lname; 
    char *number; 
}; 

Wenn Sie eine neue Instanz von struct person erstellen, müssen Sie den Speicher für jedes Mitglied einzeln zuweisen :

#define SIZE 20 // for this example, both number of contacts and size 
       // of each struct member 

struct person contacts[size]; 
for (size_t i = 0; i < j; i++) 
{ 
    contacts[i].fname = malloc(sizeof *contacts[i].fname * SIZE); 
    contacts[i].lname = malloc(sizeof *contacts[i].lname * SIZE); 
    contacts[i].number= malloc(sizeof *contacts[i].number * SIZE); 
} 

einem der Mitglieder, um die Größe, verwenden realloc:

char *tmp = realloc(contacts[i].fname, sizeof *contacts[i].fname * SIZE * 2); 
if (tmp) contacts[i].fname = tmp; 

Da realloc potenziell NULL zurückgeben kann, wird empfohlen, das Ergebnis in einer temporären Zeigervariable zu speichern, anstatt es sofort wieder dem ursprünglichen Zeiger zuzuordnen. Andernfalls riskieren Sie den Überblick über den zuvor zugewiesenen Speicher zu verlieren, was zu einem Speicherverlust führt.

Sie wollen auch verfolgen, wie viel Speicher für jedes Mitglied reserviert ist, so dass Sie vor Pufferüberläufen schützen.

Um eine der Mitglieder zu löschen, verwenden free:

free(contacts[i].fname); 

Beachten Sie, wenn Sie dynamisch eine Instanz struct person zuweisen, müssen Sie nach wie vor dynamisch jedes Mitglied zuzuweisen:

struct person *p = malloc(sizeof *p); 
p->fname = malloc(sizeof *p->fname * SIZE); 
... 

auch Diese bedeutet, dass Sie jedes Mitglied freigeben müssen, bevor Sie die Struktur Instanz selbst aufheben:

free(p->fname); 
free(p->lname); 
free(p->number); 
free(p); 

einfach befreien p wird der Speicher nicht p->fname zugeordnet befreien, p->lname und p->number.

+0

Kannst du erklären, warum ich einen Zeiger auf 'verwenden muss char 'anstelle eines Arrays von' char', um die Zuordnung aufzuheben/zu löschen? – NLhere

+0

@NLhere: weil wir Speicher dynamisch mit 'malloc' zuweisen, der immer einen Zeigerwert zurückgibt. –

0

Sie müssen die drei Felder der Struktur nicht löschen, da sie alle statisch jeweils 20 Bytes zugeordnet sind. Sie müssen den Speicher nur innerhalb der drei Felder freigeben, wenn sie dynamisch mit malloc zugewiesen werden.

Sie müssen jedoch alle dynamisch zugewiesenen Kontakte freigeben.

void deleteall(int num_entries,person*contacts)   //deleting all function 
{ 
    for(int i=0;i<num_entries;i++){ 
     free(contacts++) 
    } 

    printf("\n All contacts deleted\n\n"); 
    system("pause"); 
} 
+0

Dies erzeugt [Fehler] inkompatiblen Typ für Argument 1 von 'frei' und [Note] erwartet 'void *' aber Argument ist vom Typ 'Person' – NLhere

+0

Geändert für Sie anstelle der Zeiger Iteration –

+0

, wenn ich versuche, diese Funktion auszuführen es "funktioniert jetzt nicht mehr" und gibt eine große Zahl zurück – NLhere

0

Sie können nicht NULL zu Kontakten zuweisen [i] .fname oder Kontakte [i] .lname da diese Arrays und NULL ist ein Zeigerwert. Verwenden Sie entweder etwas wie memset() oder machen Sie vor dem Freigeben nichts mit der Struktur.