ページ 11

ポインタとfreeで解放されるメモリについての質問です

Posted: 2011年2月01日(火) 06:49
by アトラス
掲示板が新しくなってからおそらく初投稿です。アトラスです。

課題でポインタを使わないとできない問題があり、ポインタに関して理解できていない部分があるので困っています。

たとえば自己参照構造体を使ってリスト構造を作った際、要素の削除にfreeを使いますが、
それまでそこを参照していたポインタをNULLにしないとエラーが出ます。
変数のアドレスが存在しないのと、NULLは違うということなのでしょうか?


コード:



#include <stdio.h>
#include <stdlib.h>

void display();

struct test_t{
	int data;
	struct test_t *next;
};


void display(struct test_t *p){

	while(p != NULL){
		printf("%d\n",p->data);
		p = p->next;
	}
	printf("\n\n");
	return;
}

int main(){

	struct test_t *p,*q,*r;

	p = (struct test_t *)malloc(sizeof(struct test_t));
	q = (struct test_t *)malloc(sizeof(struct test_t));
	r = (struct test_t *)malloc(sizeof(struct test_t));

	p->data = 1;
	q->data = 2;
	r->data = 3;
	
	p->next = q;
	q->next = r;
	r->next = NULL;

	display(p);

	free(r);
	q->next = NULL;

	display(p);

	getchar();

	return 0;
}



Re: ポインタとfreeで解放されるメモリについての質問です

Posted: 2011年2月01日(火) 07:27
by bitter_fox
アトラス さんが書きました: たとえば自己参照構造体を使ってリスト構造を作った際、要素の削除にfreeを使いますが、
それまでそこを参照していたポインタをNULLにしないとエラーが出ます。
変数のアドレスが存在しないのと、NULLは違うということなのでしょうか?

コード:

void display(struct test_t *p){

	while(p != NULL){
		printf("%d\n",p->data);
		p = p->next;
	}
	printf("\n\n");
	return;
}

int main(){
	free(r);
	q->next = NULL; // (1)

	display(p);
}
あくまでfreeは借りていたメモリ領域をOSに返還するだけでそのアドレスはメモリ領域上に存在し続けています。(返還するとmallocで得た自由に使用する権利がなくなってしまいます)
つまり、q->nextのアドレスはfree(r)をした時点でアクセス権の無い所を指していることになります。

もしここをNULLにしなかった場合、display関数内でアクセス権の無い所を参照してしまい、OSがエラーを出します。

Re:

Posted: 2011年2月01日(火) 07:41
by アトラス
お早い返信ありがとうございます。
NULLとは全く別物ということですね、納得がいきました。
回答ありがとうございました。

Re:

Posted: 2011年2月01日(火) 07:42
by アトラス
(解決しました)