割り当てたメモリに値を設定したい

[戻る]
山田★靖 [E-Mail] 2003/02/21(金) 21:04:00
はじめまして。山田と申します。

newを使ってBYTE型で確保した領域に値を
設定したいのですが、設定の仕方がわかりません。
確保したい領域のサイズは下記のような構造体として
実際に構造体のように値をセットする為の方法を教えて
いただけないでしょうか?

-----------------------------------
・確保したい領域のサイズ
-----------------------------------
// 情報ヘッダ
typedef struct _INFOHEADER
{
DWORD    DataSize;         
WORD    DataNum;             
}INFOHEADER;
-----------------------------------
// 領域を確保する
BYTE *pInofHed; = new BYTE[sizeof(INFOHEADER)]

〜   領域に値をセットする   〜
-----------------------------------

YuO [E-Mail] 2003/02/21(金) 21:38:00
INFOHEADER *pInofHed = new INFOHEADER;
が素直だと思うのですが……。

最後に不定長配列があるなどの理由でBYTE配列が必要なら,
BYTE * pInofHedBuf = new BYTE [sizeof(INFOHEADER)];
INFOHEADER * pInofHed = reinterpret_cast<INFOHEADER *>(pInofHedBuf);
のようにすればよいです。

こうすれば,pInofHedはINFOHEADERへのポインタですから,
pInofHed->DataSize = 10;
のようにしてアクセスできます。

小悪魔恭子 2003/02/21(金) 21:38:53
INFOHEADER* p = (INFOHEADER*)new INFOHEADER;
p->DataSize = //ほにゃらら
p->DataNum = //ほにゃらら

じゃだめですか?

kazuma 2003/02/22(土) 01:04:49
「バイナリファイルに書くから勝手にパディングされたら困る。
 なおかつ、#pragma pack とか使いたくない。」

というような事情でもあるんでしょうか?

山田★靖 [E-Mail] 2003/02/24(月) 13:43:15
遅くなりまして申し訳ございません。
ご解答ありがとうございます。

なぜ、BYTE型で確保した領域で使いたいかと言うと
確保したい領域は毎回違うからです。
「32バイトの構造体をX個確保する」ような処理をしています。
-----------------------------------------------------------------
// 情報領域確保
   BYTE *pPocketInfo = new BYTE[sizeof(INFOHEADER) + 
                                (sizeof(POCKETINFO)*num)]
-----------------------------------------------------------------
上記のような処理を実際にしています。

自分の所ではメモリにデータを設定し、そのアドレスとサイズを
あるクラスに返却するというクラスを作っています。

n [E-Mail] 2003/02/24(月) 13:59:19
こんな感じでは。

INFOHEADER* pInfo = new BYTE[sizeof(INFOHEADER) + sizeof(POCKETINFO)*num];
POCKETINFO* pPocketInfo = (POCKETINFO*)(pInfo + 1);

int i;
for (i = 0; i<num; ++i) {
 pPocketInfo[i] = XXX;
}

山田★靖 [E-Mail] 2003/02/24(月) 14:16:46
ご解答ありがとうございます。
ちょっとコードで理解できない箇所が・・・

POCKETINFO* pPocketInfo = (POCKETINFO*)(pInfo + 1);
              ^^^^^^^^^^^^^^^^^^^^^^^^^
チェックした部分のコードを解説してもらえないでしょうか?
勉強不足で申し訳ございません。

n [E-Mail] 2003/02/24(月) 14:53:08
ある型のポインタに1を足すと、その型のサイズ分だけ先の位置を指すポインタが
できます。

============= <- pInfo
 INFOHEADER
============= <- (pInfo+1) == pPocketInfo == &pPocketInfo[0]
 POCKETINFO
============= <- &pPocketInfo[1]
 POCKETINFO
=============
     :

こんな感じになります。

山田★靖 [E-Mail] 2003/02/24(月) 15:51:10
わかり易い解説ありがとうございました。

実際コードに書いてコンパイルしたところ
INFOHEADER* pInfo = new BYTE[sizeof(INFOHEADER) + sizeof(POCKETINFO)*num];
の箇所で、「unsigned char *' から 'struct _INFOHEADER * に変換できない」
旨のエラーメッセージが出力されます。

YuOさんがおしゃってた方法を下記コードでも
問題なく出来るのでしょうか?
BYTE* pInfo = new BYTE[sizeof(INFOHEADER) + sizeof(POCKETINFO)*num];
POCKETINFO* pPocketInfo = reinterpret_cast<POCKETINFO *>( pInfo );

int i;
for (i = 0; i<num; ++i) {
 pPocketInfo[i] = XXX;
}

n [E-Mail] 2003/02/24(月) 16:31:46
ごめんなさいキャストが抜けてました。

 BYTE* pBytes = new BYTE[ ... ];
 INFOHEADER* pInfo = reinterpret_cast<INFOHEADER*>( pBytes );

deleteするときはpInfoでなくキャスト前のpBytesの方を渡さないといけない
みたいです。

 delete[] pBytes;

山田★靖 [E-Mail] 2003/02/24(月) 17:07:23
構造体が「ヘッダ部+データ部*num個」の場合の値の設定は理解できました。
皆様、どうもありがとうございました!
実際の処理は3つの構造体「ヘッダ部+データ部1*n個+データ部2*num個」
の情報をメモリに格納します。皆様からご教授を元にコーディングしてみました
が自信ありません・・・
データ部1にデータを設定する時、pBytes のポインタからヘッダ部のサイズ分
だけ先の位置を指させる為には、下記のようなコードでいいのでしょうか?

----------------------------------------------------------
・「ヘッダ部+データ部1*num個+データ部2*num個」の構造
================== 
 INFOHEADER
================== 
 POCKETINFO(1)
================== 
 POCKETINFO(2)
==================
 POCKETINFO(1)[n]
================== 
 POCKETINFO(2)[n]
==================     
----------------------------------------------------------
・コード

BYTE* pBytes = new BYTE[sizeof(INFOHEADER) + sizeof(POCKETINFO1)*num
                       + sizeof(POCKETINFO2)*num];
// ヘッダ部データの設定
INFOHEADER* pInfoHead = reinterpret_cast<INFOHEADER *>( pBytes );
              
// データ部1の設定
POCKETINFO1* pInfo1 = reinterpret_cast<POCKETINFO1*>( pInfoHead+1 );

// データ部2の設定
POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+2 );
----------------------------------------------------------

επιστημη 2003/02/24(月) 17:19:47
> // データ部2の設定
> POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+2 );

なぜに'2'を足す? POCKETINFO01 はいくつある?

山田★靖 [E-Mail] 2003/02/24(月) 17:32:21
>>なぜに'2'を足す? POCKETINFO01 はいくつある?

あ、すみません・・・ミスです。
'+1'です。

REE 2003/02/24(月) 17:38:32
num=3の時どちら?

(a)
================== 
 INFOHEADER
================== 
 POCKETINFO1
================== 
 POCKETINFO2
==================
 POCKETINFO1
================== 
 POCKETINFO2
==================     
 POCKETINFO1
================== 
 POCKETINFO2
==================     

(b)

================== 
 INFOHEADER
================== 
 POCKETINFO1
================== 
 POCKETINFO1
================== 
 POCKETINFO1
================== 
 POCKETINFO2
==================
 POCKETINFO2
==================
 POCKETINFO2
==================

もし(a)だと、pInfo1[n]などとは使えなくなります。

επιστημη 2003/02/24(月) 17:38:45
>>なぜに'2'を足す? POCKETINFO01 はいくつある?
> あ、すみません・・・ミスです。
> '+1'です。

はァ? じゃ POCKETINFO(1)[n] はウソ?

山田★靖 [E-Mail] 2003/02/24(月) 18:02:30
>>num=3の時どちら?
REEさんが示したくれた図の(a)になります。
'[]'つけたのは配列を意味するものではなく
POCKETINFO1のサイズを持つデータがnum個(a)の
ようにあるという事を言いたかったのです。
紛らわしくてすみません・・・

私が知りたかったのは「num=3」のような場合、どのように
すればデータを設定出来るか?という事になります。

一番最初のPOCKETINFO1は、このようなコードでデータを設定
出来ると思うのですが
POCKETINFO1* pInfo1 = reinterpret_cast<POCKETINFO1*>( pInfoHead+1 );

POCKETINFO2は「ヘッダ部+POCKETINFO1」のサイズの終端からなので
POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfoHead+1,pInfo1+1 );
みたいなコードの書き方が出来るのか?
POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+1 );
で、期待値の「ヘッダ部+POCKETINFO1」が求められるのか?
という事を質問していました。

わかりにくい質問で申し訳ございません。
皆様、よろしくお願いします。

REE 2003/02/24(月) 18:07:48
> POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+1 );

上記で大丈夫です。

επιστημηさんは(b)を前提に回答しておられるようです。

但し、このままでは、2番目以降の要素を単純に指すことは出来ませんのでご注意ください。

pInfo1[0] ・・OK
pInfo1[1] ・・NG

pInfo2[0] ・・OK
pInfo2[1] ・・NG

επιστημη 2003/02/24(月) 18:13:30
> REEさんが示したくれた図の(a)になります。

あ、そーゆーコトか。了解。

struct AB {
  struct A a;
  struct B b;
};

で、AB を n 個分確保することになるかな。

山田★靖 [E-Mail] 2003/02/24(月) 18:18:16
どうもありがとうございました。
確かにこのままでは、2番目以降の要素を
単純に指すことは出来ないですよね・・・・
2番目以降の要素を指し方を考えてみます。

わかり次第、解決にさせて頂きます。

>>επιστημηさん
紛らわしい書き方をして申し訳ございませんでした。

山田★靖 [E-Mail] 2003/02/24(月) 21:10:58
[[解決]]
2番目以降の要素ですが、なんの工夫もないですが
下記のように書きました。

// ヘッダ部の設定
INFOHEADER* pInfoHead = reinterpret_cast<INFOHEADER *>( pBytes );   
// データ部1の設定(要素1)
POCKETINFO1* pInfo1 = reinterpret_cast<POCKETINFO1*>( pInfoHead+1 );
// データ部2の設定(要素1)
POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+1 );
// データ部1の設定(要素2)
POCKETINFO1* pInfo1 = reinterpret_cast<POCKETINFO1*>( pInfo2+1 );
// データ部2の設定(要素2)
POCKETINFO2* pInfo2 = reinterpret_cast<POCKETINFO2*>( pInfo1+1 );
               ・
               ・
               ・
アドバイスくれた方々、どうもありがとうございました。

古いスレッドには追加発言できません。