STM32 C语言使用 memset清空结构体 导致改变其他结构体数据的问题

首先,在C语言中,清空结构体的方法,我们一般会采用 memset函数。
其原型是:

void * memset ( void * ptr, int value, size_t num );

函数功能: 填充内存块
将ptr指向的内存块的前num个字节设置为指定值 value(解释为unsigned char).
函数参数:

  • ptr: 指向要填充的内存块的指针。
  • value:要设置的值。该值以int形式传递,但是该函数使用此值的无符号char转换填充内存块。
  • num: 要设置为value的字节数。size_t是无符号整数类型。

在这里,我们采用的也是 memset 清空结构体。但是,由于 num 值设置的比实际的结构体字节数还要大,导致也清空了其他变量的值。

关于变量与内存的分配,我们知道:

  • 静态区:保存自动全局变量和static变量(包括static全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。
  • 栈:保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。
  • 堆:由malloc系列函数或new操作符分配的内存。其生命周期由free或delete决定。

因此,我们定义的全局变量,全部在静态区,而且,地址是连续,所以,如果在使用 memset()清空定义全局变量的数组或者结构体时。一定要确保,num 的长度 恰好是 数据或结构体占空的字节数。否则会清空其他定义的变量。

具体可以看我出错的情况:
我定义一个几个结构体:

typedef enum
{
    SLAVE_FRAME_IDLE = 0,//空闲状态
    SLAVE_FRAME_HANDER,//帧头
    SLAVE_FRAME_SLAVE_ID,//丛机ID
    SLAVE_FRAME_DRIVER_ID,//驱动板ID
    SLAVE_FRAME_OPERATE,//操作码
    SLAVE_FRAME_COMMAND,//帧命令
    SLAVE_FRAME_DATA_LENGTH,//数据量长度
    SLAVE_FRAME_FRAME_LENGTH,//帧长度
    SLAVE_FRAME_DATA,//帧数据
    SLAVE_FRAME_CRC,//校验
    SLAVE_FRAME_FINISH,//完成
}MasterUsartRxFrame_E;

typedef struct
{
    uint8_t FrameHander;//帧头
    uint8_t SlaveID;//丛机地址 ID
    uint8_t DriverID;//驱动板ID
    uint8_t Operating;//操作码
    uint16_t Command;//命令
    uint8_t DataLength;//数据长度
    uint8_t FrameLength;//帧长度
    uint16_t* pData;//数据 --> 只对写有效
    uint16_t CheckSum;//CRC校验
}SlaveFrameData_T;

typedef struct
{
    MasterUsartRxFrame_E FrameStatus;//帧状态
    SlaveFrameData_T Package;//帧包
}SlaveUsartData_T;
extern SlaveUsartData_T		tUART3_RxData;

然后,在我想清空 tUART3_RxData.Package 结构体的数据时,
本来应该是 采用:

memset(&tUART3_RxData.Package ,0,sizeof(SlaveFrameData_T));

但是,我在写的时候,写成了 SlaveUsartData_T:

memset(&tUART3_RxData.Package ,0,sizeof(SlaveUsartData_T));//bug 这里长度溢出,会导致清空其他变量

所以导致 内存静态区中,定义在 tUART3_RxData.Package 后面的变量给也给清空了。

我们可以查看 map 文件:
在这里插入图片描述在这里插入图片描述
连接在 tUART3_RxData 后面的是 tEncryptManufacture 所以,或导致,tEncryptManufacture结构体中前面几个成员清零。

事实上,也确实如此。。

因此:在使用 memset 的时候,长度一定不能溢出。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值