掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28309

関数の引数で渡したポインタをmallocした時の挙動
投稿者---rem(2006/10/04 15:02:35)


remと申します。

以下のソースに関してなのですが

void func( char* str ) { str = (char*)malloc( 1 ); }
void main() { char* str; func( str ); }

この場合、
func()関数内のmalloc()によりメモリが確保されています。
ですが、main()に戻ってきた時点で str は確保したメモリとは
別の場所を指すようになります。

しかし、

char* func() { return (char*)malloc( 1 ); }
void main() { char* str = func(); }

だとうまくいきます。

なぜなのでしょうか?



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:関数の引数で渡したポインタをmallocした時の挙動 28310 YuO 2006/10/04 15:26:46


No.28310

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---YuO(2006/10/04 15:26:46)


>以下のソースに関してなのですが
>void func( char* str ) { str = (char*)malloc( 1 ); }
>void main() { char* str; func( str ); }
>この場合、
>func()関数内のmalloc()によりメモリが確保されています。
>ですが、main()に戻ってきた時点で str は確保したメモリとは
>別の場所を指すようになります。

void func (int n)
{
    n = 100;
}
int main ()
{
    int n = 0;
    func(n);
    return 0;
}


上記プログラムで,main中のnはfunc呼び出し後においても0であることはわかっていますでしょうか。
それと全く同じ事です。



この投稿にコメントする

削除パスワード

No.28311

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---rem(2006/10/04 15:31:59)


>上記プログラムで,main中のnはfunc呼び出し後においても0であることはわかっていますでしょうか。

YuOさん、ありがとうございます。

つまりは、func()が受け取る引数が char だろうが、char* だろうが、それは値渡しと等価であるということでしょうか?

引数が char* でポインタであったとしても、func()側は

void func( char** str ) { *str = (char*)malloc( 1 ); }
void main() { char* str; func( &str ); }

としてポインタのアドレスを渡してやらないといけないということなのですね。



この投稿にコメントする

削除パスワード

No.28315

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---shu(2006/10/04 16:02:27)


素直にmain内でmallocを使えば、funcを作る必要もないです。

remさんのプログラムでは、
strの中にはよくわからないデータが入っています。
よくわからないデータを引き数でfuncに渡しています。
で、渡しっぱなしで使うこともなく、
よくわからないデータなので使えることもなく、
直ぐにmallocで上書きしています。


この投稿にコメントする

削除パスワード

No.28317

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---rem(2006/10/04 16:18:48)


>素直にmain内でmallocを使えば、funcを作る必要もないです。
まさに。

ただ、今回記したコードは私が疑問に思っている内容だけを伝えるために簡略化したものです。

引数で渡した内容を関数内でいぢるときにはアドレスを渡して
そのポインタが指す先を編集しますが、
最初に挙げた例では、一応引数としてはポインタを渡してはいるけれど、
実際にいぢられているのは関数内のローカルコピーのほうだったので、あれ?と思ったからです。

例えポインタであっても引数で渡すならば、そのアドレスを渡してやらないといけないんだなぁ。。。と思った次第です。


この投稿にコメントする

削除パスワード

No.28319

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---nano(2006/10/04 16:34:14)


>例えポインタであっても引数で渡すならば、そのアドレスを渡してやらないといけないんだなぁ。。。と思った次第です。

ptrという変数が、ある型へのポインタだとします。
このとき、ptrが指している領域の内容をfuncという
関数の中で「変更する」場合は、func関数の引数として
ptrのアドレスを渡す必要がある、ということだと思います。

ptrが指している領域の内容を「参照する」だけであれば、
func関数にptrのアドレスを渡す必要は特にありません。
まあ、アドレスを渡してもいいのですけれど、
func関数の中で「ユーザーの意図に反して」ptrが指している領域の内容が
変更されてしまう、ということをなくすには
アドレスを渡さない方がよいのでありましょう。


この投稿にコメントする

削除パスワード

No.28322

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---rem(2006/10/04 16:42:10)


>ptrという変数が、ある型へのポインタだとします。
>このとき、ptrが指している領域の内容をfuncという
>関数の中で「変更する」場合は、func関数の引数として
>ptrのアドレスを渡す必要がある、ということだと思います。
そのアドレスを渡すというところを、
元々ポインタであって、引数でもポインタを取るようにしてるんだからそれでいいんだろう。と思ってしまってました。。。

それが間違いの元でした。



この投稿にコメントする

削除パスワード

No.28318

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---YuO(2006/10/04 16:28:13)


>つまりは、func()が受け取る引数が char だろうが、char* だろうが、それは値渡しと等価であるということでしょうか?

そうです。
等価と言うより,現実問題としてCでは値渡ししかできません。

元々のremさんのコードでは,「char型へのポインタ」を値渡ししています。


>引数が char* でポインタであったとしても、func()側は
>void func( char** str ) { *str = (char*)malloc( 1 ); }
>void main() { char* str; func( &str ); }
>としてポインタのアドレスを渡してやらないといけないということなのですね。

そうです。
ポインタ値を書き換えたいのであれば,ポインタのポインタを渡さなければいけません。



この投稿にコメントする

削除パスワード

No.28323

Re:関数の引数で渡したポインタをmallocした時の挙動
投稿者---rem(2006/10/04 16:43:19)


>そうです。
>等価と言うより,現実問題としてCでは値渡ししかできません。
そうなのですね。
これですっきりしました。

皆さんありがとうございます。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧