Conversation
Notices
-
せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 20:15:27 JST せのお (妹尾 賢) 今日詰まったこと。
C言語の引数のアドレスを変更できなかった。こんな感じで,引数に渡したポインターに別のポインターを渡して,出力結果を渡そうとしたのだけど,だめだった。memcpyしたらいけたのだけど。なぜダメなのかがわからなかった。アドレスを書き換えたらダメなんだったたっけ?いや,でも引数にポインターを渡してそれを書き換えるというのはよくやるだろう?なぜだろう。
```
#include <stdio.h>
#include <string.h>
struct st {
int a;
int b;
};
struct st stg = {1, 2};
void init( struct st *str) {
str = NULL;
printf("%d, %d\n", stg.a, stg.b );
// memcpy(str, &stg, sizeof(stg));
str = &stg
}
int main(void) {
struct st st1 = {0};
printf("%d\n", st1.a);
init( &st1 );
printf("%d\n", st1.a);
return 0;
}
```- tomohiro_amami likes this.
- やきたま :sabakan: repeated this.
-
三条流菜 (bluvel@orikilli.yaruki0.net)'s status on Tuesday, 18-Sep-2018 20:29:47 JST 三条流菜 @senooken
これだと元の変数であるst1の参照は変わらない(というかこの宣言方法だと参照先は固定されてる)んでダメです。
strはst1のポインタアドレスが値として入っているだけの変数なので、strそのものを書き換えてもst1に影響は与えません。せのお (妹尾 賢) likes this. -
はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 20:34:40 JST はいこん @senooken
仮引数`str`はその関数の中でだけ有効なので、`str`をNULLとか別の構造体を指すようにしても呼び出し元の`&st1`は変わらないですね。
st1を別の場所にある実体を指すようにする意図があるのなら、`st1`はポインタにして、init()にはポインタのポインタを渡す必要がある。void init(struct st **str) {
printf("%d, %d\n", stg.a, stg.b );
*str = &stg;
}int main(void) {
struct st *st; // どこも指していない
// printf("", st1->a); // したら死ぬ
init(&st1);
printf("%d\n", st1->a);
return 0;
}せのお (妹尾 賢) likes this. -
せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:15:23 JST せのお (妹尾 賢) ありがとうございます。ああ。なるほど。この場合,アドレスが値として入ってきているだけだから, *アドレスを直接* 書き換えた場合,値渡ししているのと同じだから変わらないというわけですね。
いや,よくC言語で引数を参照渡しで,値を書き換えるというのをやっているので,同じようなイメージでやってしまいました。あちらは,*で間接参照するから変更を反映できるのであって,今回は間接参照もしていないのでダメということですね。 -
せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:21:51 JST せのお (妹尾 賢) 具体例も掲示いただいてありがとうございます。画面とにらめっこしていました。
ポインタ (アドレス) 変数の指す先を変えるには,そのポインタ変数のポインタを変えないとダメなんですね。
ポインタのポインタとかいまいち概念が理解できなかったので,誤解していました。
こちらの回答と合わせて参考になり助かりました。
https://orikilli.yaruki0.net/@Bluvel/100746538972297888はいこん likes this. -
せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:24:38 JST せのお (妹尾 賢) その場しのぎでmemcpyで書いてしまった。明日,ポインタのポインタで処理するように書きなおそう。いちいち関数とか呼ぶ必要ないもんな… In conversation permalink -
はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 21:36:25 JST はいこん @senooken
ポインタのポインタで呼び出し元のポインタを書き換えるよりは、素直に返り値としてポインタを返す方法を提案します。
struct st *init(void) {
return &stg;
}
int main(void) {
//snip...
struct st *st1 = init();
}※既にmainからstgは見えてるだろというのは置いといて
In conversation permalink -
せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 22:06:50 JST せのお (妹尾 賢) 洗いものしていて遅れました…
指摘通り,返却値で返すのが僕もいいと思うのです。しかし,今のプロジェクトでは返却値には処理結果やエラーコードを返すふうになっているので,引数でやるはめになっています…。
なお,init内でグローバル変数の代入前後に排他制御やらメモリーのアタッチ・デタッチが入るような処理を想定しています。
https://social.senooken.jp/notice/640654In conversation permalink Attachments
-
はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 22:10:10 JST はいこん @senooken あーありがちですねー。
In conversation permalink せのお (妹尾 賢) likes this.