0

データの長さがデバイスに送信するコマンドに依存する構造にデータを書き込む必要があります。そのために、次の構造を定義しました。

typedef struct {
    uint8 len;          // Command length (cmd ... crc)
    uint8 cmd;          // Command code
    uint8 data_length;  // Data length
    uint8 data[12];     // Data: max 12 Byte
    uint8 crc_h;        // CRC value MSB
    uint8 crc_l;        // CRC value LSB
}CMD_TYPE;

注:メンバーcmd、 *data_length* 、およびcrcは常に存在しますが、メンバーデータは空にすることも、最大 12 バイトまで含めることもできます。

関数に渡されたパラメーターに従って、初期化されたコマンドを返す関数を作成しました。

CMD_TYPE Device::get_cmd(uint8 cmd, uint8 data_len, uint8 *data)
{
    CMD_TYPE cmd;

    cmd.len = (4 + data_len) * sizeof(uint8);
    cmd.cmd = cmd;
    cmd.data_length = data_len;
    cmd.data = (uint8 *)realloc(cmd.data, data_len*sizeof(uint8));
    if(data_len > 0)    memcpy(cmd.data, data, data_len);

    add_crc16((uint8*)&cmd);

    return cmd;
}

関数 get_cmd() は次のように使用されます。

uint8 cmd_code = 0x01;
uint8 data[2] = {0xAB, 0xCD};

CMD_TYPE cmd = local_device->get_cmd(cmd_code, 2, data);
retVal = local_device->send(cmd);

このコードをコンパイルしようとすると、その行のコンパイラからエラーが発生します。

cmd.data = (uint8 *)realloc(cmd.data, data_len*sizeof(uint8));

コンパイラエラーは次のとおりです。

error: lvalue required as left operand of assignment

realloc()を使用する目的は、配列データのサイズを変更するか、新しいコマンド構造からまったく削除することです。私のコードで何が間違っていますか? 動的メモリ割り当てで構造体を初期化する正しい方法ですか?

4

3 に答える 3

2

あなたが望むのは、悪名高いstruct hackです:

typedef struct
{
    uint8   len;          // Command length (cmd ... crc)
    uint8   cmd;          // Command code
    uint8   data_length;  // Data length
    uint8   crc_h;        // CRC value MSB
    uint8   crc_l;        // CRC value LSB
    uint8   data[1];      // Data: max 12 Byte
} CMD_TYPE;

トリックは、 までの構造体のすべてのメンバーに十分なスペースを割り当て、メンバーにdata[]十分なバイト数を追加することdata[]です。

CMD_TYPE * allocCmd(int dataSize)
{
    int         len;
    CMD_TYPE *  p;

    len = sizeof(CMD_TYPE) + (dataSize-1)*sizeof(uint8);
    p = (CMD_TYPE *) malloc(len);
    memset(p, 0, len);
    p->data_length = dataSize;
    return p;
}

ここで、lenは、構造体のサイズから空のメンバーのサイズを差し引いた値に、配列に指定されたdata数の要素を加えたものとして計算されます。dataSizedata

問題は、実際に割り当てられている要素 (構造体の内部) 以外の要素に決してアクセスしないように注意する必要があることです。p->data[]

于 2011-09-09T15:07:46.883 に答える
0

a[..] として定義された配列は不変であり、それらに何も割り当てることはできません。代わりに、ポインターを使用する必要があります。

于 2011-09-09T14:42:04.320 に答える