0

私が次のものを持っているとしましょう:

typedef struct a_struct_s
{
     int* dynamic_pointer;
}
a_struct;

a_struct make_struct( int length )
{
     a_struct s;
     s.dynamic_pointer = calloc( sizeof( int ), length );
     // [check here to see if s.dynamic_pointer was allocated]

     return s;
}

make_struct()は struct のコピーを返すため、それsによってカプセル化されたポインタはメモリ リークし、解放できなくなりますか? また、コピー自体とs動的に割り当てることによるパフォーマンス コストはありますか?

4

4 に答える 4

2

いいえ。ポインターをコピーしても、ポインターは同じ場所を指しているため、解放できます。

于 2013-01-22T06:27:01.957 に答える
2

なぜでしょうか?ポインターは、割り当てられたメモリ自体ではありません。ポインターをコピーしても、それ自体はメモリを割り当てません。後で呼び出すfree()と、正しく解放されます。つまり、次のコードはメモリ リークを起こしません。

a_struct s = make_struct(10);
free(s.dynamic_pointer);
于 2013-01-22T06:27:24.890 に答える
1

いいえ、その観点からは問題ありませんが、メモリブロックへのポインタを使用して値で構造体を返すことはそれほど明白ではないため、呼び出し元がメンバーを解放する必要があるため、別の割り当て方法を検討することをお勧めします。初期化。

1つのアプローチは、構造体全体を割り当ててから、構造体を解放する関数を作成することです。

a_struct* alloc_struct( int length )
{
     a_struct s = calloc( 1, sizeof(a_struct) );
     s->dynamic_pointer = calloc( sizeof( int ), length );
     return s;
}

void free_struct( a_struct *p )
{
    if ( p != NULL )
    { 
      free( p->dynamic_pointer );
      free(p);
    }
}
于 2013-01-22T06:53:32.677 に答える
1

いいえ、関数の呼び出し元が構造体ポインター メンバーを呼び出す限り、free()メモリ リークは発生しません。

ルールを覚えておいてください:
を呼び出すとメモリ リークが発生し、同じアドレスで呼び出すことmalloccallocありません。freeそうする限り、メモリリークはありません。

関数から動的に割り当てられたポインターを返すときは、所有権のセマンティクスを指定することが非常に重要であることに注意してください。要するに、インターフェイスは、関数呼び出しの後、動的に割り当てられたポインター メンバーが呼び出し元によって所有されることを明示的に言及する必要があります。

make_struct()は のコピーを返すため、それstruct sによってカプセル化されたポインタはメモリ リークし、解放できなくなりますか?

はい、構造のコピーが返されますが、浅いコピーです。
基本的に、これは、返された構造体のコピーのポインター メンバーが、 の構造体ポインター メンバーが指すものと同じメモリ位置を指していることを意味しますs
両方のポインターが同じアドレスを指しているため、呼び出し元が返された構造体のポインター メンバーを呼び出している限り、freeリークは発生しません。

s動的に割り当てる場合と比較して、コピー自体にパフォーマンス コストはかかりますか?

動的割り当ては常にコストがかかり、エラーが発生しやすくなります。それらを最小限に使用し、本当に必要でない限り使用しないでください。

于 2013-01-22T06:27:22.820 に答える