我需要将数据写入一个结构,其中数据的长度取决于我要发送给设备的命令。为此,我定义了以下结构:
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()的目的是重新调整数组数据的大小,或者从我的新命令结构中删除它。我的代码有什么问题?这是使用动态内存分配初始化结构的正确方法吗?
答案 0 :(得分: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
成员的大小,加上dataSize
指定了data
的许多元素阵列。
要注意的是,你必须小心永远才能访问p->data[]
之外的任何元素,超出实际分配的内容(在结构内部)。
答案 1 :(得分:1)
您的CMD_TYPE.data
是数组,而不是指针。由于您希望它跟踪动态分配的内存,因此它必须是指针:
uint8_t * data;
请不要忘记使用malloc()
初始化它(或在realloc()
之前将其设置为零)并自行清理
顺便说一句,不投出malloc()
和co的结果。
答案 2 :(得分:0)
定义为[..]的数组是不可变的,你不能给它们分配任何东西。相反,你应该使用指针。