senooken JP Social
  • FAQ
  • Login
senooken JP Socialはsenookenの専用分散SNSです。
  • Public

    • Public
    • Network
    • Groups
    • Popular
    • People

Conversation

Notices

  1. せのお (妹尾 賢) (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;
    }
    ```
    In conversation Tuesday, 18-Sep-2018 20:15:27 JST from web permalink
    • tomohiro_amami likes this.
    • やきたま :sabakan: repeated this.
    • 三条流菜 (bluvel@orikilli.yaruki0.net)'s status on Tuesday, 18-Sep-2018 20:29:47 JST 三条流菜 三条流菜
      in reply to

      @senooken
      これだと元の変数であるst1の参照は変わらない(というかこの宣言方法だと参照先は固定されてる)んでダメです。
      strはst1のポインタアドレスが値として入っているだけの変数なので、strそのものを書き換えてもst1に影響は与えません。

      In conversation Tuesday, 18-Sep-2018 20:29:47 JST permalink
      せのお (妹尾 賢) likes this.
    • はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 20:34:40 JST はいこん はいこん
      in reply to

      @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;
      }

      In conversation Tuesday, 18-Sep-2018 20:34:40 JST permalink
      せのお (妹尾 賢) likes this.
    • せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:15:23 JST せのお (妹尾 賢) せのお (妹尾 賢)
      in reply to
      • 三条流菜
      ありがとうございます。ああ。なるほど。この場合,アドレスが値として入ってきているだけだから, *アドレスを直接* 書き換えた場合,値渡ししているのと同じだから変わらないというわけですね。

      いや,よくC言語で引数を参照渡しで,値を書き換えるというのをやっているので,同じようなイメージでやってしまいました。あちらは,*で間接参照するから変更を反映できるのであって,今回は間接参照もしていないのでダメということですね。
      In conversation Tuesday, 18-Sep-2018 21:15:23 JST permalink
    • せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:21:51 JST せのお (妹尾 賢) せのお (妹尾 賢)
      in reply to
      • はいこん
      具体例も掲示いただいてありがとうございます。画面とにらめっこしていました。

      ポインタ (アドレス) 変数の指す先を変えるには,そのポインタ変数のポインタを変えないとダメなんですね。
      ポインタのポインタとかいまいち概念が理解できなかったので,誤解していました。

      こちらの回答と合わせて参考になり助かりました。
      https://orikilli.yaruki0.net/@Bluvel/100746538972297888
      In conversation Tuesday, 18-Sep-2018 21:21:51 JST permalink

      Attachments

      1. No result found on File_thumbnail lookup.
        New status by Bluvel
        By 三条流菜 from orikilli.yaruki0.net
      はいこん likes this.
    • せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:24:38 JST せのお (妹尾 賢) せのお (妹尾 賢)
      in reply to
      その場しのぎでmemcpyで書いてしまった。明日,ポインタのポインタで処理するように書きなおそう。いちいち関数とか呼ぶ必要ないもんな…
      In conversation Tuesday, 18-Sep-2018 21:24:38 JST permalink
    • はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 21:36:25 JST はいこん はいこん
      in reply to

      @senooken
      ポインタのポインタで呼び出し元のポインタを書き換えるよりは、素直に返り値としてポインタを返す方法を提案します。
      struct st *init(void) {
      return &stg;
      }
      int main(void) {
      //snip...
      struct st *st1 = init();
      }

      ※既にmainからstgは見えてるだろというのは置いといて

      In conversation Tuesday, 18-Sep-2018 21:36:25 JST permalink
    • せのお (妹尾 賢) (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 22:06:50 JST せのお (妹尾 賢) せのお (妹尾 賢)
      in reply to
      • はいこん
      洗いものしていて遅れました…
      指摘通り,返却値で返すのが僕もいいと思うのです。しかし,今のプロジェクトでは返却値には処理結果やエラーコードを返すふうになっているので,引数でやるはめになっています…。

      なお,init内でグローバル変数の代入前後に排他制御やらメモリーのアタッチ・デタッチが入るような処理を想定しています。
      https://social.senooken.jp/notice/640654
      In conversation Tuesday, 18-Sep-2018 22:06:50 JST permalink

      Attachments

      1. No result found on File_thumbnail lookup.
        せのお (senooken@social.senooken.jp)'s status on Tuesday, 18-Sep-2018 21:35:29 JST
        By せのお (senooken@social.senooken.jp) from social.senooken.jp
        コメントありがとうございます。
        自信がなくても気軽に返信いただいてかまいませんよー。
        ご指摘の通り,ダブルポインタを使わないとだめでした。
        ありがたいことに,他にお二人からもコメントいただけて,こちらの間違いがよくわかりました。

        initという関数名は,ある処理の共通初期化処理のために,グローバル変数を取得する処理を意図しています。前後にmutexロック・アンロックとかあったりします。
    • はいこん (hcm@mastodon.home.js4.in)'s status on Tuesday, 18-Sep-2018 22:10:10 JST はいこん はいこん
      in reply to

      @senooken あーありがちですねー。

      In conversation Tuesday, 18-Sep-2018 22:10:10 JST permalink
      せのお (妹尾 賢) likes this.

Feeds

  • Activity Streams
  • RSS 2.0
  • Atom
  • Help
  • About
  • FAQ
  • TOS
  • Privacy
  • Source
  • Version
  • Contact

senooken JP Social is a social network, courtesy of senooken. It runs on GNU social, version 2.0.2-beta0, available under the GNU Affero General Public License.

Creative Commons Attribution 3.0 All senooken JP Social content and data are available under the Creative Commons Attribution 3.0 license.