2016-10-21 24 views
-2

我無法將所有條目刪除到定義的結構中。這是在「全部刪除」功能刪除C編程中的所有結構條目

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"); 
} 

問題對單個項目的缺失和我嘗試的功能代碼,他們是不兼容的類型(試圖從虛空分配到陣列)。我可以使用某種循環並使用realloc將數組縮短爲0嗎?我不確定如何清除所有條目。

回答

1

struct person成員大小是固定的,而不是從struct實例單獨分配 - 簡短的答案是,你不能調整陣列,也不能解除分配他們的存儲,而不會重新分配整個struct實例。你可以在這種情況下做的絕對最好是寫一個空字符串到每個成員以表明它不使用:

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

這不會改變數組的大小,雖然。

爲了使struct person的成員可調整和/或可刪除,您必須從struct實例本身單獨分配它們。要做到這一點,你需要將它們申報爲指針char,而不是陣列的char

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

當您創建的struct person一個新的實例,您將需要單獨分配內存的每個成員:

#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); 
} 

要調整的任何成員,使用realloc

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

由於realloc可能會返回NULL,建議您將結果保存到臨時指針變量,而不是立即將其重新分配給您的原始指針;否則可能會失去先前分配的內存,導致內存泄漏。

你也想跟蹤爲每個成員分配了多少內存,以防止緩衝區溢出。

要刪除的任何成員,使用free

free(contacts[i].fname); 

請注意,如果你動態分配的struct person一個實例,你仍然需要動態分配各成員:

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

這也意味着您必須在分配結構實例本身之前取消分配每個成員之前

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

簡單地釋放p將不會釋放分配給p->fname,p->lnamep->number的內存。

+0

您可以詳細說明爲什麼我必須使用指向' char'而不是'char'數組來取消分配/刪除? – NLhere

+0

@NLhere:因爲我們使用'malloc'動態分配內存,它總是返回一個指針值。 –

0

您不必刪除結構的三個字段,因爲它們全部靜態分配爲每個20字節。如果使用malloc動態分配,則只需要釋放三個字段中的內存。

雖然您必須釋放所有動態分配的聯繫人。

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

這會爲'free'和[Note]參數1產生[Error]不兼容的類型,但預期'void *'但參數的類型爲'person' – NLhere

+0

修改爲您使用指針迭代代替 –

+0

當我嘗試運行該函數它現在「停止工作」並返回大量數字 – NLhere

0

,因爲這些是陣列和NULL是一個指針值不能分配NULL到聯繫人[I] .fname或聯繫人[I] .lname。可以使用memset()之類的東西,或者在釋放之前不要對結構做任何事情。