考虑下面的代码:
int main(int argc, char* argv[])
{
int prt = 6;
serial_port *cprt = open_comport(prt);
int n;
while(TRUE)
{
ubx_raw *msg = malloc(sizeof(ubx_raw));
uint8_t *buf = malloc(1024*sizeof(uint8_t));
n = RS232_PollComport(cprt->nr, buf, 1024);
msg = ubx_acquire_frombuf(buf, n);
//PROBLEM
free(buf);
if (msg == NULL)
{
printf("Message scrambled or no message in the buffer!\n");
free(msg);
}
else
{
printf("Length: %" PRIu16 "\n", msg->length);
}
free(buf);
Sleep(1000);
if (msg == NULL)
{
free(msg);
}
}
return 0;
}
与功能
ubx_raw *ubx_acquire_frombuf(uint8_t *buf, int size)
{
ubx_raw *msg = malloc(sizeof(ubx_raw));
int n = 0;
//sweep through bytes
while (n < size - 1)
{
//check if start of message
if ((buf[0] == UBX_SYNC1) && (buf[1] == UBX_SYNC2))
{
//put stuff into msg
msg->length = ((uint16_t)*(buf+4));
//check if full message available, otherwise
//reduce amount to memcpy
if (msg->length < size)
{
size = msg->length;
}
//PROBLEMATIC
memcpy(&msg->data, &buf, size);
return msg;
}
else
{
n++;
continue;
}
}
return NULL;
}
每当ubx_acquire_frombuf()
调用时(在中的while
循环开始附近main
),随后的调用free(buf)
都会出现段错误。显然,buf
该功能发生了不好的事情。我知道您不能free()
塞不进去,malloc()
也不能free()
塞两次。实际上,由于指针是通过值传递的,所以内部发生的事情ubx_acquire_frombuf()
应该与main无关,对吧?
无论如何,注释掉“问题” memcpy()
(中的ubx_acquire_frombuf()
)将删除段错误。怎么会这样?我还是想用那个memcpy
!谁能阐明正在发生的事情?memcpy()
不应该编辑要复制的源(即buf
),对吗?
PS歉意没有一个最小的例子,但是我无法从头开始重现问题。我不确定发生了什么,但是没有什么异常(例如,对我编写的其他函数的调用),ubx_acquire_frombuf()
因此这与一个最小的示例相差不远。
编辑:由大众需求:
typedef struct {
uint8_t *data;
uint16_t length;
} ubx_raw;
您标记为有问题的代码确实有问题:
// PROBLEMATIC
memcpy(&msg->data, &buf, size);
问题是您正在将size
字节复制到该字段msg->data
(因为您msg->data
要将的地址传递给memcpy),但是该字段只是一个大小很小的指针。因此memcpy将覆盖ubx_raw
结构的其余部分,然后覆盖内存中的所有内容,其中将包括的一些malloc
内部会计信息。
你可能是说
// PROBLEMATIC
memcpy(msg->data, &buf, size);
但这仍然是有问题的,因为msg->data
从未初始化过。因此,更可能的解决方案是:
// NOT PROBLEMATIC but don't forget to free(msg->data) before free(msg).
msg->data = malloc(size); // Check for non-NULL
memcpy(msg->data, &buf, size);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句