您的位置:首页 > 其它

未操作的变量值自动修改--强制类型转换导致变量覆盖

2017-09-18 16:33 465 查看
最近在软件调试过程中遇到一个很奇怪的问题,最终查明的原因是函数内部一个局部变量在被函数调用(值传递而非地址传递)之后,变量莫名被修改,导致程序运行异常。

我把问题代码提炼如下:

// test_enum.cpp : 定义控制台应用程序的入口点。

#include <stdio.h>
#include <stdlib.h>

#define uint32_t unsigned int
#define uint16_t unsigned short int
#define uint8_t  unsigned char

typedef enum boolean_e
{
RET_FALSE = 0 ,
RET_TRUE
} boolean_t;

int dba_proc_stat_get(uint8_t olt_id, boolean_t  *bw_dn_table_sw_index_stat)
{
uint32_t data = 0;

data = olt_id & 0x11;

//*bw_dn_table_sw_index_stat = (boolean_t)(data & 0x1);
*bw_dn_table_sw_index_stat = (boolean_t)(data | 0x12345678);

return(0);
}

int main()
{
uint32_t  olt_id = 4;
uint8_t   bw_dn_table_sw_index_stat = 0xAA;

printf("%s: olt_id = %u\r\n", __FUNCTION__, olt_id);

dba_proc_stat_get(olt_id, &bw_dn_table_sw_index_stat);

printf("After add: olt_id = %u\r\n", olt_id);

printf("bw_dn_tables_set OK.\r\n");

return 0;
}
代码运行结果如图所示:



可以看到,无符号32位整型变量 olt_id 初始值为4,运行后,结果变为 18。

然后调试代码,找到 无符号32位整型变量 olt_id 和无符号8位整型变量bw_dn_table_sw_index_stat 的地址,确定他们之间有何联系:

olt_id 的地址 和 bw_dn_table_sw_index_stat 的地址如下:



可以看到 olt_id 和 bw_dn_table_sw_index_stat 的 地址相隔 3 个地址,打印从 0xbfffede4 开始的 8 个地址:



函数调用执行完后,olt_id 的 值确实发生了改变,变为 0x12345678 (小端模式),分析至此,原因豁然明朗:

枚举类型占用 4 个字节,在对 bw_dn_table_sw_index_stat 进行赋值时使用强制类型转换,导致从 0xbfffede5 开始后的 4 个字节数据被修改,而 olt_id 的地址刚好位于这一区间的最后一个字节地址: 0xbfffede8,于是 olt_id 被覆盖。

总结:

(1)枚举类型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,一般占用 4 个字节内存(依据不同的系统而定);

(2)强制类型转换时,数据截断一般是安全的,但数据扩展应当注意变量覆盖问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐