Hatena::ブログ(Diary)

Sickly Life はてな版 このページをアンテナに追加 RSSフィード

2011-11-20

C言語・malloc・ポインタのポインタ

| 18:09 | C言語・malloc・ポインタのポインタを含むブックマーク C言語・malloc・ポインタのポインタのブックマークコメント


私の一方的な勘違いでご迷惑をおかけしてしまい、大変申し訳ございませんでした。

修正や削除をするか考えたのですが、残すことにしました。攻撃的な書き方をしているので、不快な思いをされる可能性があります。閲覧にはご注意下さい。

※23時50分。見出し修正しました。


よく分からないことが書かれたページを見かけた。

mallocのスコープ

よく分からない点その1、『mallocのスコープ』。mallocで確保した領域の寿命は、基本的にfreeするまでかプログラムが終了するまでのはずなので、テストするまでもない。

よく分からない点その2、『引数での値渡しはできない』。C言語には値渡ししか存在しないので、値渡しが出来ないわけがない。

ページ中のソースコードにも気になる点がある。

p=(param*)malloc(sizeof(struct param)*3);

*3って何?

p1=NULL;
p2=NULL;

p2=test(p1);
param *test(param* p){
if (p1 != NULL)	{

test関数にNULLを渡してどうするのさ?ソースコードをどう見ても、p1がNULL以外になるはずがないのだが、ブログ主ポインタをちゃんと理解していないのだろうか。

もしp1とp2が同じ内容になることを期待してるのなら、以下のようにダブルポインタポインタポインタ)を使う必要がある。

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

typedef struct param
{
	int id;
	char cd[2 + 1];
} param;

param * test(param **p)
{
	*p = malloc(sizeof(param));
	(*p)->id = 10;

	strcpy((*p)->cd, "11");
	printf("func p id : %d\n", (*p)->id);
	printf("func p cd : %s\n", (*p)->cd);

	return *p;
}

int main(void)
{
	param *p1 = NULL;
	param *p2 = NULL;

	p2 = test(&p1);

	if(p1 == NULL)
	{
		printf("p1 : NULL\n");
	}
	else
	{
		printf("p1 id : %d\n", p1->id);
		printf("p1 cd : %s\n", p1->cd);
		printf("p1 : %p\n", p1);
		printf("&p1 : %p\n", &p1);
	}

	if(p2 == NULL)
	{
		printf("p2 : NULL\n");
	}
	else
	{
		printf("p2 id : %d\n", p2->id);
		printf("p2 cd : %s\n", p2->cd);
		printf("p2 : %p\n", p2);
		printf("&p2 : %p\n", &p2);
	}

	return EXIT_SUCCESS;
}

以下のような結果になる。

func p id : 10
func p cd : 11
p1 id : 10
p1 cd : 11
p1 : 0x8f8e008
&p1 : 0xbfb66918
p2 id : 10
p2 cd : 11
p2 : 0x8f8e008
&p2 : 0xbfb6691c

tama-jptama-jp 2011/11/20 21:45 ポインタがわかっておりません主です。
指摘ありがとうございます。勉強になります。
ただ、コメント書いてくださればいいのになぜ?このような書き方を。。。。ちょっと悲しいです。

itiriitiri 2011/11/20 23:39 ケンカを売るようなキツイ書き方をしてしまって、本当にすみません。
そちらのブログにもコメントを書きました。お読み頂ければ幸いです。

tama-jptama-jp 2011/11/22 02:08 itiri さん
すみません、前回何をしたかったかというと、構造体の動的配列を作成したかったのです。
処理スピードを上げるためにこのようなやり方をするのですが、
仕事上、いろいろあって思考回路が吹っ飛んでましたw

ご一読いただければ幸いです。<(_ _)>

動的配列の構造体:
http://d.hatena.ne.jp/tama-jp/20111122

でも、これってメモリのフリーの仕方がよくわかってませんよねw。。。。。
ではでは。

itiriitiri 2011/11/22 19:50 拝見しました。
なるほど、前のソースの*3や[0]はそういうことだったのですね。
コメント欄が表示されなかったので、一つ前の記事にコメントしました。
ご確認下さい。

http://d.hatena.ne.jp/tama-jp/20111119/1321684718#c

tama-jptama-jp 2011/11/22 20:32 itiri さん

たびたびすみません。やっぱり、C言語の仕様を、私は、わかってないですわ。
もぅ一度、K&Rの本読み直しておきます。

本題ですが、
*p=malloc(sizeof(struct param *)*n);
も、
*p = a;
Macのgccでは、両方とも必要がないみたいですよ。

ただ、以下のところは必要です、
for (int i=0;i<n;i++) {
p[i]=&a[i];
}
これでうまくLinkできるのは、なぜなんでしょうかね????
「p」は、アドレスじゃないんですね。
C言語側の便宜上の文字であって、アドレスを確保する場所を
メモリ空間(ここではヒープかな?)に持たせなくていいんすね。
アセンブリ的に考えるとポインタ用の箱がいると考えてしまうんですが、、、、

意外と勉強になりますね。。。。

コメント書き込みLinkが、宣伝の下にでているようです。
また、暇があればちょくちょくつついてやってください。

ではでは。

トラックバック - http://d.hatena.ne.jp/itiri/20111120/1321780179
リンク元