質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

880閲覧

構造体型ポインタ変数のアドレス先のメモリについて

hikar

総合スコア13

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/04 07:33

Youtuberゲーム導館さんの動画を参考にさせていただいて、テクスチャマッピング製作をしているのですが、画像を読み込む際に行うメモリの確保について、初歩的なところですが、わからないところがあったので質問させていただきました。

下のソースコードで、memcpy(&pixels[y * bi.biWidth + x],&bits[y * bi.biWidth + x],sizeof RGB);
memcpy関数で転送先の&pixelsに転送元の&bitsをコピーしていると思うのですが、この処理のxで1加算しポインタ変数に1足したアドレスにコピーを繰り返し行っているとおもうのですが、&bitsにはどのような値が入っているのか疑問に思ったので、質問させていただきました。

「int *bits」このような書き方をすれば、 int型ポインタ変数ができ、bitsには整数を格納することができる。 格納先のアドレスには整数が格納されている。

RGB* bits = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);
構造体型ポインタ変数bitsを先に宣言することによって、 bitsの1番目のアドレスにはRGB(unsigned char r, g, b)のunsigned char 型の3つの数値が格納できるということでしょうか?

どなたかわかる方おしえてください<(_ _)>

C++

1 typedef struct { 2 unsigned char r, g, b; 3 }RGB; 4 RGB* bits = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight); 5 fread(bits, sizeof RGB, bi.biWidth * bi.biHeight, pFile); 6 7 for (int y = 0; y < bi.biHeight; y++) 8 for (int x = 0; x < bi.biWidth; x++) { 9 RGB* pbits = &bits[y * bi.biWidth + x]; 10 //printf("%p\n",pPixels); 11 unsigned char temp = pbits->r; 12 pbits->r = pbits->b; 13 pbits->b = temp; 14 15 } 16 17 for (int y = 0; y < bi.biHeight / 2; y++) 18 for (int x = 0; x < bi.biWidth; x++) { 19 RGB* pbits0 = &bits[y * bi.biWidth + x]; 20 RGB* pbits1 = &bits[(bi.biHeight - 1 - y) * bi.biWidth + x]; 21 RGB temp = *pbits0; 22 *pbits0 = *pbits1; 23 *pbits1 = temp; 24 } 25 26 typedef struct { 27 unsigned char r, g, b, a; 28 }RGBA; 29 RGBA* pixels = (RGBA*)malloc(sizeof RGBA * bi.biWidth * bi.biHeight); 30 31 for (int y = 0; y < bi.biHeight;y++) 32 for (int x = 0; x < bi.biWidth; x++) { 33 memcpy(&pixels[y * bi.biWidth + x],&bits[y * bi.biWidth + x],sizeof RGB);//転送先のアドレス、転送元のアドレス 34 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

パッと見24bit(RGB)の画像をRとBをひっくり返して、上下もひっくり返して
32bit(RGBA)へ変換しているコードなんでしょうかね?
(アルファ値の部分が未定義な気もしますが)

memcpyは
https://www.google.com/search?q=memcpy
で検索してもらえば分かる通り、メモリー領域をコピーする関数です。

RGB* bits = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);

構造体型ポインタ変数bitsを先に宣言することによって、 bitsの1番目のアドレスにはRGB(unsigned char r, g, b)のunsigned char 型の3つの数値が格納できるということでしょうか?

sizeof RGBはたぶん3(環境依存)で、画像の高さ、幅を掛け算していますので、
たとえば100x100ピクセルの画像であれば

RGB* bits = (RGB*)malloc(3 * 100 * 100);

を実行したことになります。
で、最初の画素にはbits[0]としてアクセスができます。
r要素だったらbits[0].rですね。

で、memcpyはアドレスを渡す必要がありますので、
bits[0]ではなく&bits[0]のようにアンパサンドを付けてアドレスにしてあげているだけです。

&bitsにはどのような値が入っているのか

bitsはポインタ変数、
bits[n]はn要素目の実体(用語正しいか自信ないですが)
&bits[n]はn要素目のアドレスです。

&はbitsではなくbits[n]に掛かっていると考えてください。

投稿2020/03/04 08:08

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hikar

2020/03/05 00:49

なるほど!完全に理解出来ました。(人''▽`)ありがとうございました。<(_ _)>
guest

0

「int *bits」このような書き方をすれば、 int型ポインタ変数ができ

までは正しいですが、
bitsに格納できるのはあくまでも「int型が格納されている変数を指し示すアドレス」であって、
bitsに直接int型を格納することは出来ません。

実際にint型を格納するためには、そのための領域を確保しておかないと、不適切なメモリに変数を代入してしまう可能性があります。

実際に領域を確保して、ポインタ変数と紐付けるには2つ方法があります。

1つ目は

C

1int a; 2bits = &a;

という、普通に変数宣言してそのアドレスをポインタ変数に代入する方法。

2つ目は、参考にしているものにあるように

C

1bits = (int *)malloc(sizeof(int))

として動的にメモリ確保をする方法。

つまり、

C

1RGB* bits = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);

だと、bitsにはRGB * bi.biWidth * bi.biHeightのサイズ分確保されたメモリの先頭アドレスが入ります。

動的にメモリ確保をした場合は、メモリが不要になった時点で必ずfree(bits)と、
メモリ解放するのを忘れないでください。

投稿2020/03/04 08:06

riko111

総合スコア149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hikar

2020/03/05 00:50

アドレスについて再度勉強してみます。(人''▽`)ご返答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問