2010-11-30 3 views
0

メモリを割り当てているとします。割り当てられたメモリを別のタイプとして扱う

char* buffer = (char*)my_malloc(2062); 

ヘッダーという名前の定義済み配列から最初の14バイトにchar値を割り当てます。

memcpy(buffer, header, 14); 

次に、割り当てられた残りの領域をfloatへのポインタとして扱いたいと思います。

float* float_buffer = (float*)(buffer + 14); 
some_function(float_buffer); 

その後、ある時点ですべてのデータを送信する必要があります。

transmit(buffer); 
my_free(buffer); 

この正しい方法でメモリを扱うことはできますか?浮き*キャストは大丈夫ですか?私は価値を失い、正しい結果を得られない問題を抱えています。 私の質問です: 割り当てられたメモリを別の種類として扱う必要があるが、処理の最後にchar *として送信する必要がある場合.....これは正しい方法ですか?

私はptr値をチェックしました。これらはfloat *とchar *のときは同じですが、正しい結果が得られません。

私の制限の1つは、静的バッファから最初に1ブロックのメモリしか割り当てることができないということです。そのため、別のmallocを別の型(float *)として呼び出すことはできません。

+0

アライメントの問題があるように私に聞こえます。予想される結果と実際のエラーを表示できますか? –

+0

はい、それは、アライメントの問題...私が知らなかったものでした。私はここからそれを取ることができます。ありがとうございました。 –

答えて

3

この問題を解決するには、少なくともfloat_bufferがsizeof(float)で整列されていることを確認する必要があります。 sizeof(float) - 余分な1バイトを割り当て、mallocの呼び出しをmodulo sizeof(float)の結果を観察し、適切な最初の数バイトを無視することで、これを行うことができます。 (あなたは、もちろん、無料()の呼び出しを行うために、周りの元のポインタを維持する必要があります。)

あなたはおそらくしかし、これを行うにはしたくありません。 'バッファ'の目的は、ネットワークなどを介して送信されるデータを蓄積することであり、浮動小数点数は他の場所からコピーされることになります。実際に行うべきことは、逆にキャストすることです:バッファをchar []として常に扱い、それらをコピーするときにソースの浮動小数点数を文字列として再解釈します。それは私がここに推測しています

char* buffer = malloc(total_size); 
char* float_start = buffer + header_size; 
memcpy(float_start, (char*)float_source, sizeof(float) * float_count); 
transmit(buffer, total_size); 
free(buffer); 
+0

+1アライメントの頭痛を避けるには良い解決策です。 –

+0

ありがとうございました。 –

0

ですが、malloc関数のプロトタイプは、あなたが、本質的にそう後でバッファの別のチャンクをキャスト、char *にvoid *型のバッファをキャストしている

void *malloc(size_t size); 

であるため、浮動小数点数*は、ポインターの適切な管理に注意する限り、問題ありません。

3

概念的には、これは問題ありませんが、確実に動作するようにするには追加作業が必要です。

任意のアドレスにfloatとしてアクセスするだけでは問題が発生する可能性があります。 malloc()によって返されたアドレスが正しく任意の型としてアクセスのために整列させる必要がありますが、そのアドレスに14を追加すると、すべてのベットは(charを除く)オフになっていている - 特定アライメント要件があるかもしれません。

正しいアラインメントを確保するには、bufferに追加するアドレスがsizeof(float)の倍数であることを確認する必要があります。 - パディング - あなたの文字と自分の山車の間を

#define PAD_OFFSET(offset, type) ((offset) + sizeof(type) - 1) & ~(sizeof(type) - 1)) 

float *float_buffer = (float *)(buffer + PAD_OFFSET(14, float)); 

注意これは、ギャップが作成されること:あなたは次の式を使用してパディングを追加していることを行うことができます。

また、あなたはstructを定義することができ、コンパイラはあなたのためにパディングを把握します。これは柔軟な配列メンバーと呼ばれるC99機能を使用しています。

struct foo { 
    char abc[14]; 
    float xyz[]; 
}; 

struct foo *buffer = malloc(2062); 
memcpy(&buffer->abc, header, 14); 
some_function(&buffer->xyz); 
transmit(buffer); /* Presuming transmit() expects a void * parameter. */ 

あなたはパディングせずにそれをを行いたい場合は、直接フロートとしてbufferでメモリをアクセスすることはできません - あなたは一時的な配列を作成する必要があります

float temp[500]; /* Or whatever size */ 
some_function(&temp); 
memcpy(buffer + 14, temp, sizeof temp); 
+0

ありがとうございました。 –

関連する問題