2017-08-07 32 views
-2

私は、charポインタをdoubleポインタに変換しなければならない関数を持っています。もともとコードは(double *)dataと書かれていましたが、データはchar *ですが、これはcppcheckを "互換性のないバイナリデータ表現"として警告していました。 Cスタイルのメソッド。char *をdouble *に変換するにはどうすればよいですか?

私はstatic_castdynamic_cast、およびreinterpret_castを試しましたが、正しく動作していません。 atofはダブルに変換できますが、lvalue required as unary ‘&’ operandと書いてあるので、ダブル*でこれを使用することはできません - double *vd = &atof(data) - ここで

は、私が働いているものの例である:

exStateData convertToStateData(char* data, int size) { 
    ... 
    unsigned int vd_size = *((unsigned int*) data); 
    data += sizeof(unsigned int); 
    ... 
    double *vd = (double*)data; 
    return exStateData(vd, vd + vd_size); 
} 

私は、二重*へのchar *にキャストできますか?

+4

あなたがしようとしていることとその理由は、まったく明確ではありません。あなたがしようとしていることを理解するのに十分なコードを教えてください。 –

+2

[最小、完全、および検証可能な例](https://stackoverflow.com/help/mcve)を作成して表示できますか?注:MCVEには、さまざまなサンプル入力(すべての側面を示す)と望ましい出力が含まれている必要があります。 – Akira

+0

また、あなたが 'atof'の戻り値のアドレスを取ることができたとしても、それは良いことではありません。この値は、そのステートメントが完了するとすぐに存在しなくなります。したがって、存在しない一時的な一時アドレスを持つことになります。 (試してみると、いくつかの誤解があなたの質問の背後にあるかもしれないことが示唆されていますが、もしかしたらどうすればいいかわかりません) –

答えて

0

C++の厳密なエイリアシング規則は、どのタイプにもポインタを安全にキャストできないことを意味します。他の型に合法的に別名を付けることができる唯一の型はchar,unsigned charおよびstd::byte(C++ 17)です。あなたがする必要があることを理由

は正しく整列double(または任意の他のタイプ)にあなたのchar*ソースからのデータをコピーします。例えば

double get_from_char_array(char const* buffer) 
{ 
    // correctly aligned double 
    double d; 

    // get the address of the double and convert it 
    // to a char pointer because char pointer can alias 
    // any other type 
    char* dp = reinterpret_cast<char*>(&d); 

    // copy the data out of the buffer into the 
    // memory occupied by the double d 
    std::copy(buffer, buffer + sizeof(double), dp); 

    return d; 
} 

doubleのバイナリ表現は、標準によって指定されていないので、この方法でdouble変換しても、必ずしもプラットフォーム間でポータブルではないことに注意してください。

0

それを行うための安全な方法は、memcpyのを使用することです:

exStateData convertToStateData(char* data, int size) { 
    ... 
    unsigned int vd_size; 
    memcpy(&vd_size, data, sizeof(vd_size)); 
    data += sizeof(vd_size); 
    ... 
    std::vector<double> vd(vd_size); 
    memcpy(&vd[0], data, vd_size*sizeof(double)); 
    return exStateData(&vd[0], &vd[0] + vd_size); 
} 

問題は、これはコピーの多くが含まれていることです。しかし、問題はdataがおそらくダブルのために適切に整列されていないことです。

(これを行うと、最後の行で呼び出すexStateDataのオーバーロードを変更して、ベクターへの参照を取得したい場合があります。

関連する問題