web-dev-qa-db-ja.com

解放後のポインタ変数への再割り当て

これは合法ですか?解放された後、何かにptrを割り当てることはできますか?

int * ptr = (int*) malloc(sizeof(int));
free(ptr);
ptr = (int *) malloc(sizeof(int));
15
skmiley1

ポインタを解放した後で再割り当てするのではなく、ptr変数を再利用するだけです。これはまったく問題ありません。

25
Mureinik

まず、コメントで述べたように、 malloc()とfamilyの戻り値をCでキャストしない理由については、この説明を参照してください。

そうは言っても、ここでは(再)割り当ては問題ありません。

実際、質問の文言

解放された後、何かにptrを割り当てることはできますか?

読む必要があります

解放された後、ptrwithに何かを割り当てることができますか?

何を推測しますか、free- ingのない割り当ても、Cのようにlegalですが、サイドとして メモリリーク が作成されます変数ptrがメモリアロケータ関数の戻り値を保持していたため、使用が終了したらメモリを解放する必要があります。ポインタのコピーを保持せずにポインタを再割り当てすると、アロケータ関数によって割り当てられたメモリにアクセスできなくなり、free()する方法がなくなります。

ポインタが静的に割り当てられた変数のアドレスを保持していた場合、(nned to)を解放することはできず、直接の再割り当てはまったく問題ありません。以下のスニペットについて考えてみてください。

int x = 5, y = 10;
int * p = &x;
//do something with p
p = &y; //this is fine, just a re-assignment.
7
Sourav Ghosh

はい。 C言語で有効です。

詳細については、関連するスタックオーバーフローの質問: Cで解放されたポインタを再利用

cwe.mitre.org によると:

このシナリオでは、問題のメモリは、解放された後のある時点で有効に別のポインタに割り当てられます。解放されたメモリへの元のポインタが再び使用され、新しい割り当て内のどこかを指します。データが変更されると、有効に使用されているメモリが破損します;これにより、プロセスで未定義の動作が発生します。

6
msc

これは合法ですか?解放された後、何かにptrを割り当てることはできますか?

はい、これは合法です。 ptrは、何度でも再割り当てできます。たとえば、ポインタを再割り当てするために、そのポインタを解放する必要はありません。

int * ptr = malloc(sizeof(int));
int *temp_ptr = ptr;         // temp_ptr is pointing to the location ptr is pointing
ptr = malloc(sizeof(int));   // ptr points to new location.

mallocの戻り値をキャストしないように注意してください。

5
haccks

解放された後、何かにptrを割り当てることはできますか?

_int * ptr = (int*) malloc(sizeof(int)); /* line 1 */
free(ptr); /* line 2 */
ptr = (int *) malloc(sizeof(int)); /* line 3 */
_

あなたの質問を次のように受け止めます:

"以前の動的割り当て(1行目)からこのポインターが指していたメモリが解放された後(2行目)、動的に割り当てられたばかりのメモリのアドレスをポインターに割り当てることは合法ですか(3行目)? "

次に、この答えはイエスです。


3行目も有効ですなし 2行目があります。それでも、free()(2行目)を呼び出さない場合は、ptr(1行目)に割り当てられた値)は上書きされ(3行目)、これによりptrの初期値でfree()を呼び出す可能性が失われ、プログラムは最初に割り当てられたこのメモリを正確にリークします。

5
alk

はい、ヒープとそのリーガルに新しいメモリを割り当てています。

代わりにreallocを使用することをお勧めします。

realloc()が失敗した場合、 c11 、§7.22.3.5章から

新しいオブジェクトを割り当てることができなかった場合、realloc関数は... nullポインタを返します。

そして

[....]新しいオブジェクトのメモリを割り当てることができない場合、古いオブジェクトの割り当ては解除されず、その値は変更されません。

Reallocを使用する適切な方法は次のとおりです。

ptr_new = realloc(ptr, sizeof(int)*2);
if (ptr_new == NULL)
{
    free(ptr);
}

また、 mallocの戻り値をキャストしない理由 もお読みください。

3
kocica

はい。それは完全に合法です。 ptrは、その内容に関係なく存在し続けるスタンドアロン変数です。 ptrが格納されているメモリ位置には何も起こりません。それに値を割り当てることを妨げるものは何もありません。メモリ割り当て(malloc/reallocなど)の正確さは別の話ですが、変数(メモリ位置)を再利用してメモリ位置のアドレスを格納することに問題はありません。

3

ポインタを宣言すると、メモリ位置が割り当てられます。その場所は再割り当てできます。

malloc()呼び出しで値を割り当てた後、その前にfree()に値を割り当てた場合、これはメモリリークです。 free()の後で再割り当てでき、リークは発生しません。もう一度free()することを忘れないでください。

実際、決して終了しない便利なプログラムであるオペレーティングシステムは、プロセスへのいくつかの固定ポインタを常に再割り当てし、プロセスが終了したときにそれらを解放します。

割り当てが許可されていないプログラミングは、functional programmingと呼ばれます。

2
alinsoar