我已将邮箱简化为以下代码。 我有一个SetMsg(),GetMsg()和ClearMsg()函数。 在SetMsg()中,我的目的是存储消息,直到调用GetMsg(),此时存储的消息将返回给调用者,同样,我的目的是将先前存储的消息转换为NULL。
但是,由于我不是malloc
任何事情,我想知道将信息存储在ptr_Msg
中是否完全安全,就像我在下面做的那样?由于我无法控制在{I"已保存"之后存储msg
的内存会发生什么。它ptr_Msg
,msg
的内存后来被som的其他变量分配,而我仍然指向那个地址?或者static
声明ptr_Msg
?拯救一天?
例如,msg
在发送到signal
时会带有成员SetMsg()
,并将其存储在ptr_Msg
中。然后,在此函数范围之外,msg
更改其signal
的值。如果我收到GetMsg()
,我会返回signal
的新值或达到SetMsg()
时的值吗?
我应该做这样的事吗?在SetMsg()
Msg* tmp = (Msg*) msg;
ptr_Msg = (Msg*) malloc(sizeof *tmp);
memcpy(ptr_Msg, tmp, sizeof *tmp);
然后在ClearMsg()
free(ptr_Msg);
ptr_Msg = NULL;
当前代码:
typedef struct Msg {
uint16_t signal;
} Msg_t;
static Msg_t* ptr_Msg = NULL;
bool GetMsg(char** msgData, uint16_t* sigNo) {
*msgData = (char*) ptr_Msg;
// Get message
if (*msgData != NULL) {
// do some stuff
// and then
ClearMsg();
return true;
}
return false;
}
bool SetMsg(void* msg) {
if (ptr_Msg!=NULL) {
return false;
}
ptr_Msg = (Msg*) msg;
return true;
}
void ClearMsg() {
ptr_Msg = (Msg*) NULL;
}
编辑和可能的答案: 我设法得到了这个测试,当然,它没有水。 我已将代码更改为以下内容,似乎可以正常工作。我已使用"< ===新代码部分===>"标记了部件。
是否正确/安全地使用malloc和free?
typedef struct Msg {
uint16_t signal;
} Msg_t;
static Msg_t* ptr_Msg = NULL;
bool GetMsg(char** msgData, uint16_t* sigNo) {
*msgData = (char*) ptr_Msg;
// Get message
if (*msgData != NULL) {
// do some stuff
// and then
ClearMsg();
return true;
}
return false;
}
bool SetMsg(void* msg) {
if (ptr_Msg!=NULL) {
return false;
}
// <=== new code section ===>
ptr_Msg = malloc(sizeof *ptr_Msg);
memcpy(ptr_Msg, (Msg_t*) msg, sizeof *ptr_Msg);
// <=== ===>
return true;
}
void ClearMsg() {
// <=== new code section ===>
free(ptr_Msg);
// <=== ===>
ptr_Msg = (Msg*) NULL;
}
答案 0 :(得分:0)
您的代码是围绕单个文件范围变量ptr_Msg
的复杂包装器。这些函数定义了一个接口。此接口是与调用者签订的有关指针ptr_Msg
引用的数据所有权的合同。只要合同未知,就不可能说你是否需要复制数据而不是存储指针。对于当前实现,调用者负责数据的生存时间至少持续指针引用数据的时间。如果您需要一个负责存储某些数据的容器(或邮箱),则需要使用类似的memcpy复制数据。
主要问题是,你想要什么? 合同是什么? 什么存储?