C语言 分段错误错误.我正在尝试解析有效负载并提取值并返回值.我犯了什么错误?



msg 包含一个有效负载,格式为 |tag|length|value| 标签的大小和长度为 2 个字节。值的大小在长度内描述, 数据类型可以是 uint16、uint32 或 uint8。

typedef struct
{
response_uint16_t msg[5];
}payload;
void func(response_uint16_t *msg, int type)  
{
int *posPtr = NULL;
void *temp;
int valueLen = msg->length;
posPtr = &msg->tag;
posPtr += sizeof(msg->tag);
posPtr += sizeof(msg->length);
posPtr++;                         //ideally this should now point to value.
if(type == 1)
{
memcpy((U8*)temp, *posPtr, valueLen);
return(*temp);
}
if(type == 2)
{ 
memcpy((U16*)temp, *posPtr, valueLen);
return(*temp);
}
}
int main()
{
payload *P;
p = (struct payload*)malloc(sizeof(p));
int res;
/*assumne the msg is filled here and value expected to be filled here is of type U16 */
res =(U16)func(&p->msg[1], 2); 
res =(U8)func(&p->msg[2], 1);
.
.
}

此代码片段中存在几个问题:

  1. 正如@Tibrogargan所评论的,temp指针在初始化之前被访问(复制到(;

  2. 指针posPtr被声明为int *,但它似乎是按字节前进的。

posPtr = &msg->tag;            // <== pointing to `tag`
posPtr += sizeof(msg->tag);    // <== pointing to element after `tag`, i.e. `length`? NO! Advanced for two integers width since size of (msg->tag) should be 2 as you said
posPtr += sizeof(msg->length); // <== pointing to element after `length`, i.e. `value`? NO! Same reason

假设您的平台整数为 32 位宽。你说"标签的大小和长度是 2 个字节"。所以posPtr += sizeof(msg->tag)实际上是posPtr += 2.posPtr += sizeof(msg->length)的情况相同。

initial posPtr --> +----------------------------+
| tag    | __two_bytes_pad__ |
posPtr+1 --> +----------------------------+
| length | __two_bytes_pad__ |
posPtr+2 --> +----------------------------+
| value                      |
+----------------------------+

同样,即使没有上述问题,以下行中的注释看起来也是错误的。posPtr外观应指向value之后的下一个元素。无论如何,在不知道您的实际数据结构的情况下,我无法确切地说出posPtr指向何处。但这行值得仔细检查。

posPtr++;                         //ideally this should now point to value.
  1. 您假设结构已打包,但通常不是,如果在定义结构时未指定,请参阅结构填充和打包以获取更多详细信息。

  2. 指针temp声明为void *因此不能直接取消引用。

  3. 返回func的类型为void,因此不能返回任何值。

  4. 在尝试访问value时,您可能会假设字节序。

您需要使用如下所示的malloccalloc为变量temp分配内存:

int valueLen = msg->length;
size_t valueSize = type ==1 ? sizeof(U8) : sizeof(U16);
void *temp = malloc(valueLen * valueSize);

然后执行memcopy,以避免因将某些内容复制到变量temp而导致Undefined behaviour,这通常但不总是导致Seg错误,如@Tibrogargan

最新更新