1

大規模ではありますが、かなり単純なシステム設定があります。格納するデータは、必要な精度の間またはそれに応じてvoid*変化する可能性があるため、データを配列に格納します。floatdouble

実行するだけで、 MinGWを使用してdelete [] dataレイズします。そして、がaかaかを示すwarning: deleting 'void*' is undefined [enabled by default]別の変数がありますが、どちらを使用するかは重要ですか?datafloat*double*

言い換えれば、メモリリークや、コンパイラによって検出されないその他のエラー/損傷を心配することなく、休眠コードを使用できますか?

double* d_data = new double[length];
data = (void*)d_data;
delete [] (float*)data;
4

3 に答える 3

3

それは確かに重要です。使用するポインターdelete[]は、割り当てたポインターと同じタイプである必要があります。したがって、へdouble*のキャストは有効です(ただし、エラーが発生しやすくなります)。にキャストするとfloat*、未定義の動作が発生します。

[クラスタイプの単一オブジェクト(配列ではない)には例外があります。基本クラスに仮想デストラクタがある場合は、基本クラスへのポインタになる可能性があります。doubleただし、これは、や配列などのプリミティブ型には適用されません。]

メモリリークについて:手動のメモリ管理は、例外をスローする可能性のあることを絶対に行わないように細心の注意を払わない限り、常にメモリリークの危険性がありますRAIIを使用してすべての動的リソースを管理することを強くお勧めします。

于 2013-03-06T23:52:21.347 に答える
1

ユニオンを使用したいようです。

于 2013-03-06T23:46:56.010 に答える
0

はい、それは重要です(そして、他のデータ型へのキャストは、本質的に離れるのと同じくらい悪いvoid*です)。なぜなら、追加のメタデータ(実際の長さなど)を本質的に失ったり、ねじ込んだりするからです。ただし、本質的に未定義の動作であるため(コンパイラやバージョンが異なれば、生成される結果も異なる可能性があります) 、必ずしもクラッシュするわけではありません(たとえば、コンパイラが間違いに気付かない限り、使用することもできますがdelete data;delete [] data;リークする可能性があります)。

Jorgeが提案したように、これにはユニオンを使用するだけで、2つのデータ型が同じメモリを共有できます。

union my_union {
    double d_double;
    float d_float;
};

コンパイラーによっては、この構造体は通常、内部の最大のデータ型と同じサイズになります(この場合(および32ビットマシンの場合)、doubleの場合はおそらく8バイト、floatの場合は4バイトです。したがって、合計サイズは8になります。これらの変数は本質的に重複しているため、バイト)。これをある種の自動変換には使用できないことに注意してください。

于 2013-03-06T23:55:26.140 に答える