2016-10-21 3 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インスタンスとは別に割り当てられていない - 短い答えは、あなたが配列のサイズを変更することができないということです、でもあなたは全体structインスタンスの割り当てを解除しなくてもストレージの割り当てを解除することができます。あなたは、この場合に行うことができます絶対的な最高のは、それが使用されていないのです示すために、各メンバーに空の文字列を記述することです:

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

これは、しかし、配列のサイズを変更しません。

struct personのメンバーをサイズ変更および/または削除できるようにするには、structインスタンスとは別にインスタンスを割り当てる必要があります。 charの配列とは反対に、あなたは、ポインタcharとして、それらを宣言する必要があることを行うには:あなたがstruct personの新しいインスタンスを作成するとき

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

を、あなたは個別に各メンバーのためのメモリを割り当てる必要があります。 :

#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を使用し、メンバーのいずれかを削除するには

:あなたは動的struct personのインスタンスを割り当てた場合、あなたはまだ、動的に各メンバーを割り当てる必要があること

free(contacts[i].fname); 

注:

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

これもあなたは、構造体のインスタンス自体を解放し前に、各メンバーの割り当てを解除しなければならないことを意味します

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

は単にpp->fnamep->lname、そしてp->numberに割り当てられたメモリを解放しません解放します。

+0

を追加するために ' 'char'の配列の代わりに' char'を使います。 – NLhere

+0

@NLhere:常にポインタ値を返す 'malloc'でメモリを動的に割り当てるためです。 –

0

構造体の3つのフィールドがすべて20バイトずつ静的に割り当てられているため、構造体の3つのフィールドを削除する必要はありません。 mallocで動的に割り当てられている場合は、3つのフィールド内のメモリを解放するだけです。

動的に割り当てられたすべての連絡先を無料にする必要があります。

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] expected 'void *'の引数1に互換性のない型を生成しますが、引数は 'person'型です – NLhere

+0

代わりにポインタの反復を使用するように修正されました –

+0

今すぐ "停止"して大きな数字を返します – NLhere

0

これらの配列であり、NULLポインタ値であるため、あなたが.lname [i]は[I] .fnameコンタクト連絡先にNULLを割り当てることはできません。 memset()のようなものを使うか、解放する前に構造体で何もしないでください。 struct person

関連する問題