函数 return 后未清除本地结构和字符数组内存
Local structs and character arrays memory is not cleaned after function return
我在处理字符串消息的函数中声明了几个字符数组和结构。此函数会定期调用,我注意到变量与上一次函数调用具有相同的数据。
void handle_incoming_message(void)
{
// All further variables keep previous value
message_fields msg_params;
message_data msg;
char base_response[16];
char payload_response[14];
char tx_msg[50];
char response_buf[128];
if(is_valid_msg(&msg, &msg_params) == 1u) // Check if there is message in queue and Checksum is ok
{
/* Get all message fields into struct */
get_msg_fields(&msg_params, &msg);
........
}
}
这会导致错误,所以当我处理邮件并转发邮件时,邮件已损坏,
从上一条消息中获得一些额外的数据(见图)。第一个终端是原始消息,2d 是重定向的。
我还在调试模式下检查过,变量在下次调用时显示相同的值,在它们以某种方式被使用之前。(见图)。 response_buf 函数调用 2d 次时的数据。
为什么会这样?函数 return 之后局部变量不应该被清除吗?处理这种情况的正确方法是什么?
更新:Message_fields 添加了结构。
typedef struct message_fields{
uint8_t sender_id;
uint32_t payload_fields[NOF_PAYLOAD_FIELDS];
uint8_t receiver_id;
uint16_t msg_id;
uint8_t payload_length;
char payload_type;
char payload[128];
uint8_t checksum;
uint8_t peripheral_id;
} message_fields;
如果局部变量没有显式初始化,它们的值是不确定的。您不能依赖它们具有任何特定的价值,事实上,如果您尝试阅读它们,您可以调用 undefined behavior。通常,实现不会在创建时尝试清除它们。这是使 C 语言快速的原因之一。
您的代码应该使用适当的默认值显式初始化您正在读取的任何未初始化的变量,以便它的行为具有确定性。
函数内声明的未显式初始化的局部变量可以有任何值 - 并且将包括任何先前调用函数的值'left over' .标准并未指定您的特定编译器和构建系统如何为此类变量实现内存。
为防止因使用此类未初始化数据而产生的问题,请在您的代码中添加显式初始化程序。以下将所有 'local' 数据设置为零(您没有为我们提供 message_fields
和 message_data
的定义,所以我为它们提供 'possible' 初始值设定项):
void handle_incoming_message(void)
{
// All further variables keep previous value
message_fields msg_params = { 0, };
message_data msg = { 0, };
char base_response[16] = { 0, };
char payload_response[14] = { 0, };
char tx_msg[50] = { 0, };
char response_buf[128] = { 0, };
if (is_valid_msg(&msg, &msg_params) == 1u) // Check if there is message in queue and Checksum is ok
{
/* Get all message fields into struct */
get_msg_fields(&msg_params, &msg);
........
}
}
我在处理字符串消息的函数中声明了几个字符数组和结构。此函数会定期调用,我注意到变量与上一次函数调用具有相同的数据。
void handle_incoming_message(void)
{
// All further variables keep previous value
message_fields msg_params;
message_data msg;
char base_response[16];
char payload_response[14];
char tx_msg[50];
char response_buf[128];
if(is_valid_msg(&msg, &msg_params) == 1u) // Check if there is message in queue and Checksum is ok
{
/* Get all message fields into struct */
get_msg_fields(&msg_params, &msg);
........
}
}
这会导致错误,所以当我处理邮件并转发邮件时,邮件已损坏, 从上一条消息中获得一些额外的数据(见图)。第一个终端是原始消息,2d 是重定向的。
我还在调试模式下检查过,变量在下次调用时显示相同的值,在它们以某种方式被使用之前。(见图)。 response_buf 函数调用 2d 次时的数据。
为什么会这样?函数 return 之后局部变量不应该被清除吗?处理这种情况的正确方法是什么?
更新:Message_fields 添加了结构。
typedef struct message_fields{
uint8_t sender_id;
uint32_t payload_fields[NOF_PAYLOAD_FIELDS];
uint8_t receiver_id;
uint16_t msg_id;
uint8_t payload_length;
char payload_type;
char payload[128];
uint8_t checksum;
uint8_t peripheral_id;
} message_fields;
如果局部变量没有显式初始化,它们的值是不确定的。您不能依赖它们具有任何特定的价值,事实上,如果您尝试阅读它们,您可以调用 undefined behavior。通常,实现不会在创建时尝试清除它们。这是使 C 语言快速的原因之一。
您的代码应该使用适当的默认值显式初始化您正在读取的任何未初始化的变量,以便它的行为具有确定性。
函数内声明的未显式初始化的局部变量可以有任何值 - 并且将包括任何先前调用函数的值'left over' .标准并未指定您的特定编译器和构建系统如何为此类变量实现内存。
为防止因使用此类未初始化数据而产生的问题,请在您的代码中添加显式初始化程序。以下将所有 'local' 数据设置为零(您没有为我们提供 message_fields
和 message_data
的定义,所以我为它们提供 'possible' 初始值设定项):
void handle_incoming_message(void)
{
// All further variables keep previous value
message_fields msg_params = { 0, };
message_data msg = { 0, };
char base_response[16] = { 0, };
char payload_response[14] = { 0, };
char tx_msg[50] = { 0, };
char response_buf[128] = { 0, };
if (is_valid_msg(&msg, &msg_params) == 1u) // Check if there is message in queue and Checksum is ok
{
/* Get all message fields into struct */
get_msg_fields(&msg_params, &msg);
........
}
}