1

将来 memcpy を介して、以前に動的に割り当てられたメモリを含む構造体を含むバッファにメモリを割り当てたいと思います。

つまり、私は構造体を持っています

struct test_struct {
    int   num;
    char  *values;
};

長さ の文字列の量がtest_struct.values含まれています。ポインタが割り当てられたメモリのサイズを取得できないことはわかっているので、 を介して追跡するだけです。この構造体のサイズを取得する最も簡単でクリーンな方法は何ですか?numLENGTHnum

私が思いつくことができる唯一の解決策は、次のようなものです

buf = malloc(sizeof(test_struct) + (num * LENGTH));

しかし、私はこの低レベルのメモリ管理に慣れていないので、もっと良いものがあるかもしれません.

4

3 に答える 3

4

2 つの構造体を memcpy する場合は、両方のメモリが連続している必要があります。しかし、num事前に決定する必要があります。

struct test_struct {
    int num;
    char ** values;
} * TestStruct;

int _num = 0;

// find _num

TestStruct = malloc (sizeof (struct test_struct) + (sizeof(char*) * _num) + (LENGTH * _num));

TestStruct->num = _num;
TestStruct->values = &TestStruct + sizeof (struct test_struct);

for (int i = 0; i < _num; i++){
    TestStruct->values[i] = &TestStruct + sizeof (struct test_struct) + (i * LENGTH);
}

char * を char ** に変更した理由は、char * を使用すると、最初の文字列の後に文字列にアクセスするのが難しくなるためです (文字列が null で終了していると想定しています)。また、memcpy を呼び出した後、新しい構造体のすべての文字列ポインターを更新する必要があります。

memcpy を実行するには、次のようにします。

memcpy (buf, TestStruct->values[0], LENGTH * TestStruct->num);

ただし、buf では、最初の文字列しか表示されません (文字列が null で終了していない場合を除きます)。numバッファの最後に到達したことが でわかるまで、null で終了するすべての文字の後にポインタをインクリメントする必要があります。


リクエストの内容について理解が深まりましたので、次の点を考慮してください。

UDP パケットを使用している場合は、期待どおりの順序でデータが到着するように、データを 1 つのパケットで送信する必要があります。複数のパケットが送信されると、順不同で到着する場合があります。このため、データのサイズが 512 バイト以下 (UDP パケットの最大サイズ) であることを確認する必要があります。また、すべてのデータが連続したメモリにあることを確認する必要があります。この例で提供した構造体にデータが既にあると仮定します。

// this function puts the struct in contiguous memory

int PrepareBuffer (struct test_struct TestStruct, char ** buffer){

    char * cast = (char *) &TestStruct->num;

    * buffer = malloc ((TestStruct->num * LENGTH) + sizeof (int));

    for (int i = 0; i < sizeof (int); i++) *buffer[i] = cast[i];

    for (int i = 0; i < (TestStruct->num * LENGTH); i++) *buffer[i + sizeof (int)] = TestStruct->values[i];
    return 0;
}

バッファを にマップする別の関数を受信側に実装する必要がありますstruct test_struct。また、わかりやすくするためにエラー チェックを省略しました。メモリを割り当てる前に、パケットの大きさを確認する必要があります(<= 512 である必要があります)。また、malloc が null 以外のポインターを返すことを確認する必要があります。

于 2013-05-31T20:39:55.383 に答える
0

4 バイト (32 ビット Linux の整数用) と char * (32 ビットでは 64 は 8) 用に 4 バイトを割り当てる必要があるだけです。

あなたが本当に求めているのは、char *value が指す領域に割り当てる必要があるメモリの量をどのように知るかということです。あなたがやっているwyaでこれを理解します。次に、値を buf の場所に設定します。複数の文字列がある場合の正しい方法であるコメントがあり、その領域でそれらをすべて一緒にジャムして、どれが自分であるかを把握する必要はありません。

于 2013-05-31T20:40:08.237 に答える
0

値が指す構造体とバッファの両方にメモリを割り当てたいと想定しています。もしそうなら、これは正しいです。余分なスペースを指すには、次のようにしますbuf->values = buf + 1;(これは buf を次のように宣言すると仮定しています)。struct test_struct buf;

于 2013-05-31T20:42:58.317 に答える