new で返ってきたポインタをキャストする – プログラミング – Home

new で返ってきたポインタをキャスト...
 
通知
すべてクリア

[解決済] new で返ってきたポインタをキャストする


壱
 壱
(@壱)
ゲスト
結合: 14年前
投稿: 9
Topic starter  

WindowsXP(SP3) VC++2008使ってます。
c++初心者です。

Wave(音楽ファイル)のデータを読み込むプログラムを作成中なのですが、
Microsoft DirectX SDK (June 2010)ライブラリを参考にしてます。
その中で少し疑問に思うところがあったので、ご教授願えたらと思います。
// Allocate the waveformatex, but if its not pcm format, read the next
// word, and thats how many extra bytes to allocate.
if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
{
m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) ];
if( NULL == m_pwfx )
return 0;//( Lm_pwfx, E_FAIL );
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
m_pwfx->cbSize = 0;
}
else
{
// Read in length of extra bytes.
WORD cbExtraBytes = 0L;
if( mmioRead( m_hmmio,
( CHAR* )&cbExtraBytes, sizeof( WORD ) ) != sizeof( WORD ) )
return エラー;

m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX )+cbExtraBytes ];
if( NULL == m_pwfx )
return エラー;
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
m_pwfx->cbSize = cbExtraBytes;

// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
if( mmioRead( m_hmmio,
( CHAR* )( ( ( BYTE* )&( m_pwfx->cbSize ) ) + sizeof( WORD ) ),
cbExtraBytes ) != cbExtraBytes )
{
if( m_pwfx ){ delete m_pwfx; m_pwfx = 0; }
return エラー;
}
}

m_pwfx は WAVEFORMATEX* です。
WAVEFORMATEXやpcmWaveFormatとはMMSystem.hに定義されている構造体です。
質問したいことなのですが、
m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) ];
という文は
m_pwfx = new WAVEFORMATEX;
と何か違いがあるのでしょうか。
また、配列newしていると思うのですが、エラーの際にdelete m_pwfxという記述があり
ますが、これはdelete[] m_pwfxでなくていけないのではないでしょうか。
もしかしたらすごくお門違いな質問かもしれません。
よろしくお願いします。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 14年前
投稿: 40
 

> m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) ];
> という文は
> m_pwfx = new WAVEFORMATEX;
> と何か違いがあるのでしょうか。

前者は WAVEFORMATEX のコンストラクタを実行しません。
裏を返せば、WAVEFORMATES にコンストラクタが定義されていないなら、
意味としては(ほぼ)同じと言えます。

> また、配列newしていると思うのですが、エラーの際にdelete m_pwfxという記述があ

> ますが、これはdelete[] m_pwfxでなくていけないのではないでしょうか。

コンストラクト時との整合をとるため、正しくは:

CHAR* p = new CHAR[ sizeof( WAVEFORMATEX ) ];
m_pwfx = ( WAVEFORMATEX* )p;
...
delete[] p;

もしくは

m_pwfx = new WAVEFORMATEX();
...
delete m_pwfx;


返信引用
壱
 壱
(@壱)
ゲスト
結合: 14年前
投稿: 9
Topic starter  

επιστημη様、レスありがとうございます。

確かに!
この文だとコンストラクタは呼ばれませんよね。
気付きませんでした!
WAVEFORMATEXにコンストラクタやデストラクタはありませんが、
きっと製作する途中で何かあってこういう形になったんだろう、ということで
理解して先に進むことにします。
分かり易い説明で頭のもやもやが取れました。
ありがとうございました。


返信引用
壱
 壱
(@壱)
ゲスト
結合: 14年前
投稿: 9
Topic starter  

解決チェック忘れました


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
 

m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX )+cbExtraBytes ];
っていう文もあるから,このまま単純に
解決されていますんで余談なんですけどね。。。

m_pwfx = new WAVEFORMATEX();
と同じって理解でいいのかなぁ?

m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX )+cbExtraBytes ];

delete m_pwfx;
だと
普通に考えるとあれ?って思うね

こっから乗っかちゃいますけど
でも,new CHAR[size]ってsize文の連続した領域って考えると,
最終的には
::calloc(size,sizeof(CHAR))と同義?
ってことは,ヒープ領域の確保時のヘッダ?的には領域の最初に確保時のサイズがあるなら

delete m_pwfx;で全て解放してくれそうな気もするし,
sizeof(WAVEFORMATEX)の分しか解放しないんじゃないか?って気もするし…

不思議。。。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

要するに WAVEFORMATEX は可変サイズ構造体なわけで。
http://msdn.microsoft.com/ja-jp/library/cc371559.aspx
cbSize が非0のとき、追加データがあるってことで
> m_pwfx->cbSize = cbExtraBytes;

なので、この例は new char [] でも new WAVEFORMATEX でもうまくない。
可変長構造体をポータブルに実装するには malloc/calloc を使うしかないだろう。
new char[] は(初期値指定ない場合)0クリアされないので
calloc よりは malloc に近い。

移植性があって安全で無駄な0クリアしないのは
p_pwfx=(WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)+cbExtraBytes);
free(p_pwfx);

まあもっとも VC++ の POD 配列の new/delete は malloc/free で実装されているので
話を VC++ に限定するなら実害はないわけだが。

new が NULL を返すことはない (nothrow な new を呼んでいないし) ので、
提示サンプルはなんだか非常に微妙な感じ。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました