こんばんわ。
以下のようなchar型の配列を直接Fooにキャストして利用したいのですが、
Foo構造体のdataにはint型の配列として利用したいのですが可能でしょうか?
char型の配列を直接Fooにキャストした後にdataの部分を操作すれば
可能かと思っていたのですがうまくいきません。
foo->data=new int*[2];
としてしまうとbytData[8]が破壊されてしまいます。
このような方法は無理でしょうか?
struct Foo
{
int tenmp ;
int count ;
int** data ;
} ;
char bytData[ 4 + 4 + 8 ] = { 1, 0, 0, 0,
2, 0, 0, 0,
3, 0, 0, 0,
4, 0, 0, 0,
} ;
int _tmain(int argc, _TCHAR* argv[])
{
Foo*foo ;
foo = reinterpret_cast< Foo* >( bytData ) ;
foo->data = (int**)&bytData[ 8 ] ;// ここがダメ。
printf( "%d\n", *foo->data[ 0 ] ) ;// 3
printf( "%d\n", *foo->data[ 1 ] ) ;// 4
return 0 ;
}
No.3ベストアンサー
- 回答日時:
ポインタと配列の違いを、もういちどちゃんと勉強しなおした方がいいと思います。
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++ではこれでは問題になることがあります
早々のご返答ありがとうございます。
とても参考になます。改めて勉強不足を実感しました。
また環境を書いていませんでした。大変失礼しました。
No.4
- 回答日時:
いやいや, 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 でそうなってるしここを変える必然性はないと思うので今でも大丈夫じゃないかな. ほぼ「メンバが隙間無く並んでいるか?」も大丈夫だとは思うけどこっちが成り立つ必然性はない.
早々のご返答ありがとうございます。
とても参考になり、改めて勉強不足を実感しました。
また環境を書いていませんでした。
お手数をおかけして申し訳ありません。
No.2
- 回答日時:
やるとすれば 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のような使い方です …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# Makefileのechoの展開について 2 2022/07/26 07:35
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- その他(プログラミング・Web制作) zshの例外処理 1 2022/06/02 16:36
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
C言語の2次元配列 容量が大き...
-
配列の要素数に変数を入れたい...
-
define で 配列
-
C言語の配列のコピーについて
-
構造体のextern方法
-
ポインタを使って構造体の配列...
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
コンボボックスでデフォルト値...
-
エラー:浮動小数点の不正な使用
-
c言語
-
配列の不正アクセスについて
-
c言語プログラミング 等差数列...
-
bmpやImageの配列を関数の引数...
-
C言語から質問です。
-
100個の要素を持つ1次元配列に1...
-
C#でのフィボナッチ数列
-
C言語 ファイルの指定された行...
-
配列における数値の比較について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
c言語
-
構造体のextern方法
-
define で 配列
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
コンボボックスでデフォルト値...
-
2番目の最大値を求める
-
C言語の2次元配列 容量が大き...
-
C#で配列が空かを判定するには?
-
MFCのCArrayを使った二次元配列
-
C言語の課題が出たのですが自力...
-
C言語 ファイルの指定された行...
-
Cのエラー
-
ポインタを使って構造体の配列...
-
配列のアドレス部
-
char型配列をint型に代入するには
-
MFC - ダイアログボックスのPic...
-
C言語から質問です。
おすすめ情報