- ベストアンサー
ポインタのアドレスについて
- char型の配列を直接Fooにキャストして利用したいが、Foo構造体のdataにint型の配列として利用することはできるか
- foo->data=new int**[2]としてしまうとbytData[8]が破壊されてしまうため、別の方法を模索している
- foo->data = (int**)&bytData[8]の部分がうまくいかないので、そもそもこの方法は無理だと考えている
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ポインタと配列の違いを、もういちどちゃんと勉強しなおした方がいいと思います。 foo = reinterpret_cast< Foo* >( bytData ) ; の後では アドレスbyData : foo->tenmpの領域 : 値=0x00000001 アドレスbyData+4 : foo->countの領域 : 値=0x00000002 アドレスbyData+8 : foo->dataの領域 : 値=0x0000000400000003 となっています。 dataは int**ですから、 data[0] は 「dataの値が示すアドレスにある、 int *の値」 です。 アドレス 0x0000000400000003 : foo->data[0]の領域: 仮に 0x1000000000000000 とする *foo->data[ 0 ] とすれば、「上記のアドレスが示すアドレスにある、intの値」となります。 アドレス 0x1000000000000000 : *foo->data[ 0 ]の領域: 仮に 0x000000010 とする → printf( "%d\n", *foo->data[ 0 ] ) ;// 0x000000010 = 16 foo->data=new int*[2]; では、 foo->dataの領域に、 new int*[2]の結果が代入されます。 new int*[2] で 0x2000000000000000 が確保されたとすると アドレスbyData+8 : foo->dataの領域 : 値=0x2000000000000000 よって > bytData[8]が破壊されてしまいます というのは当り前の現象です。 struct Foo { int tenmp ; int count ; int data[2] ; } ; と配列で宣言すると、dataとして int2個分の領域がFooの中に確保されます。 アドレスbyData : foo->tenmpの領域 : 値=0x00000001 アドレスbyData+4 : foo->countの領域 : 値=0x00000002 アドレスbyData+8 : foo->data[0]の領域 : 値=00000003 アドレスbyData+12 : foo->data[1]の領域 : 値=0x00000004 となる *** 可能性はあります *** ですが ○sizeof(int)がいくつになるか? ○メンバがこの順番に並んでいるか? ○メンバが隙間無く並んでいるか? ○3,0,0,0 は 3なのか、0x03000000 なのか、それ以外なのか といったことが、コンパイラ,CPU,OS,設定等によって違ってくることがあります。 精通している人が理解した上で、十分に注意して使う(でも使いたくない)裏技です。 // 特に、C++ではこれでは問題になることがあります
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
いやいや, int が 4バイトかつ 4バイトアラインと仮定すれば foo->data=new int*[2]; で「bytData[8]が破壊される」のは明らかでしょ? むしろ何をどう考えたら「破壊されない」と思えるのかが知りたいよ. 端的にいえば int x = 1; x = 2; とやったときに「x が 1 のままでないのはおかしい」って思うか, ってことなんだけど.... ちなみに「メンバがこの順番に並んでいるか?」だけは (その場合) 規格で保証されているはずです>#3. 今の規格 (C++11 and/or C++14) を持っていないの「はず」としておくけど, C++98 でそうなってるしここを変える必然性はないと思うので今でも大丈夫じゃないかな. ほぼ「メンバが隙間無く並んでいるか?」も大丈夫だとは思うけどこっちが成り立つ必然性はない.
お礼
早々のご返答ありがとうございます。 とても参考になり、改めて勉強不足を実感しました。 また環境を書いていませんでした。 お手数をおかけして申し訳ありません。
- redfox63
- ベストアンサー率71% (1325/1856)
やるとすれば Fooの定義を struct Foo { int tenmp; int count; int* data[1]; }; といった具合に定義してやる方法だと思います Foo* foo; foo = einterpret_cast< Foo* >( bytData ); // これは不要 // foo->data = (int**)&bytData[ 8 ] ;// ここがダメ。 printf( "%d\n", *foo->data[ 0 ] ) ;// 3 printf( "%d\n", *foo->data[ 1 ] ) ;// 4 WinAPIで使う BITMAPINFOのような使い方です …
お礼
早々のご返答ありがとうございます。 ビットマップを読み込んだことがありましたのでなるほどと思いました。
- wormhole
- ベストアンサー率28% (1626/5665)
不可能です。
お礼
早々のご返答ありがとうございます。 他の方の意見も踏まえて無理だと判断しました。
お礼
早々のご返答ありがとうございます。 とても参考になます。改めて勉強不足を実感しました。 また環境を書いていませんでした。大変失礼しました。