73

私がこの構造体を持っているとしましょう

typedef struct person{
    char firstName[100], surName[51]
} PERSON;

そして私はmallocによってスペースを割り当て、いくつかの値で埋めています

PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
strcpy(testPerson->firstName, "Jack");
strcpy(testPerson->surName, "Daniels");

その構造体が使用するすべてのメモリを解放するための正しく安全な方法は何ですか?「free(testPerson);」です 十分ですか、それとも各構造体の属性を1つずつ解放する必要がありますか?

それは私を別の質問に導きます-構造はどのようにメモリに保存されますか?奇妙な動作に気づきました。構造体のアドレスを出力しようとすると、最初の属性のアドレスと同じになります。

printf("Structure address %d == firstName address %d", testPerson, testPerson->firstName);

つまり、このfree(testPerson)はこのfree(testPerson-> firstName);と等しくなければなりません。

それは私がやりたいことではありません。

ありがとう

4

7 に答える 7

87

簡単な答え:free(testPerson)十分です。

、またはfree()を使用してメモリを割り当てた場合にのみ使用できることを忘れないでください。malloccallocrealloc

あなたの場合、あなたtestPersonは十分に解放するためのメモリを制限しているだけです。

その場合、名前を保存するために使用char * firstname , *last surNameしたことがある場合は、メモリを割り当てている必要があります。そのため、各メンバーを個別に解放する必要がありました。

これは、逆の順序である必要がある点でもあります。つまり、要素に割り当てられたメモリは後で実行されるためfree()、最初にオブジェクトへのポインタを解放します。

各要素を解放すると、以下に示すデモが表示されます。

typedef struct Person
{
char * firstname , *last surName;
}Person;
Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct
ptrobj->firstname = malloc(n); // memory allocation for firstname
ptrobj->surName = malloc(m); // memory allocation for surName

.
. // do whatever you want

free(ptrobj->surName);
free(ptrobj->firstname);
free(ptrobj);

この背後にある理由は、最初に解放すると、ポインタptrobjによって割り当てられたメモリであるメモリリークが発生するためです。firstnamesuName

于 2012-11-27T18:40:29.223 に答える
7

まず、以下の場合にメモリを定義して割り当てるときに、どのくらいのメモリが割り当てられるかを知っておく必要があります。

   typedef struct person{
       char firstName[100], surName[51]
  } PERSON;
  PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));

1)sizeof(PERSON)は151バイトを返すようになりました(パディングは含まれません)

2)151バイトのメモリがヒープに割り当てられます。

3)解放するには、free(testPerson)に電話します。

しかし、あなたがあなたの構造を次のように宣言するなら

  typedef struct person{
      char *firstName, *surName;
  } PERSON;
  PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));

それから

1)sizeof(PERSON)は8バイトを返すようになりました(パディングは含まれません)

2)malloc()またはcalloc()を呼び出して、firstNameとsurNameにメモリを割り当てる必要があります。お気に入り

        testPerson->firstName = (char *)malloc(100);

3)解放するには、構造体を解放するよりも、最初に構造体のメンバーを解放します。つまり、free(testPerson-> firstName); free(testPerson-> surName); free(testPerson);

于 2012-11-27T18:49:50.857 に答える
5

structを配列で構成されていると定義したためchar、2つの文字列構造であり、解放するstructだけで十分です。またstruct、配列を解放して保持する方法もありません。その場合、のようなことをしたいと思うでしょうstruct { char *firstName, *lastName; }が、それからあなたは名前のために別々にメモリを割り当てて、いつそのメモリを解放するかという問題を処理する必要があります。

余談ですが、解放された後も名前を保持したい理由はありますか?struct

于 2012-11-27T18:41:10.787 に答える
3

この方法では、フィールドは構造の一部として割り当てられる静的サイズの配列であるため、構造を解放するだけで済みます。これは、表示されるアドレスが一致する理由でもあります。配列は、その構造の最初のものです。フィールドをchar*として宣言した場合は、手動でmallocして解放する必要があります。

于 2012-11-27T18:42:32.497 に答える
3

free十分ではありませんfree。メモリを未使用としてマークするだけで、構造体データは上書きされるまでそこにあります。安全のため、ポインタをのNULL後に設定しますfree

元:

if (testPerson) {
    free(testPerson);
    testPerson = NULL;
}

struct配列のようなもので、メモリのブロックです。オフセットを介して構造体メンバーにアクセスできます。最初の構造体のメンバーはオフセットに配置される0ため、最初の構造体のメンバーのアドレスは構造体のアドレスと同じになります。

于 2016-03-02T04:30:43.867 に答える
2

マロックとフリーはペアにする必要があります。

mallocは、Personに十分な大きさのメモリのチャンクを取得しました。

解放すると、mallocに、「ここ」から始まるメモリが不要になったことを通知します。これにより、割り当てられた量がわかり、解放されます。

電話するかどうか

 free(testPerson) 

また

 free(testPerson->firstName)

free()が実際に受け取るのはアドレス、同じアドレスだけで、どちらを呼び出したかはわかりません。ただし、free(testPerson)を使用すると、コードがはるかに明確になります。これは、mallocと明らかに一致します。

于 2012-11-27T18:41:22.480 に答える
2

動的に割り当てられていないタイプを解放することはできません。配列は構文的には似ていますが(int* x = malloc(sizeof(int) * 4)同じように使用できますint x[4])、呼び出すfree(firstName)と後者のエラーが発生する可能性があります。

たとえば、次のコードを考えてみましょう。

int x;
free(&x);

free()ポインタを取り込む関数です。&xポインタです。このコードは、単に機能しない場合でも、コンパイルされる可能性があります。

すべてのメモリが同じ方法で割り当てられていると仮定するとx、定義で「割り当て」られ、2行目で「解放」され、スコープの終了後に再び「解放」されます。同じリソースを2回解放することはできません。エラーが発生します。

xこれは、特定の理由で、プログラムを閉じずにメモリを解放できない可能性があるという事実についても言及していません。

tl; dr:を解放するだけで、struct大丈夫です。配列を無料で呼び出さないでください。動的に割り当てられたメモリでのみ呼び出します。

于 2012-11-27T18:42:52.600 に答える