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

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

我把问题代码提炼如下:

// 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)强制类型转换时,数据截断一般是安全的,但数据扩展应当注意变量覆盖问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值