成员函数里memset(this,0,sizeof(*this))会发生什么

this里面可能包含string之类的对象,把这些对象清零会导致非法数据。

即使一个类现在是POD,维护升级之后可能就不再是POD了。因此memset(this,0,sizeof(*this))是一种危险的写法。
 

 

没有virtual function,没有vtable,同时class当中没有包含其他class成员的class可以用这个。
/******************************************************************************** * @file :servo.c * @brief :servo 温度检测传感器驱动 * @Author :Gwen9 * @Date :2024/08/05 * @Version :V1.0 初始版本 *******************************************************************************/ #include "driver_conf.h" #ifdef DRIVER_SERVO_ENABLED /* Private Typedef -------------------------------------------------------------------*/ typedef struct _S_SERVO { my_timer_id xId; my_timer_chn_t xChn; }s_servo; /* Private Functions Declare ----------------------------------------------------------*/ static int servo_set_angle(const c_servo* p_obj, float angle); /* Private Variables -------------------------------------------------------------------*/ /* Public Functions -------------------------------------------------------------------*/ c_servo servo_create(my_timer_id xId, my_timer_chn_t xChn) { c_servo new = {0}; //新建一个空的GPIO对象 int ret; /*为 SERVO 新对象的私有成员申请内存 同时清空内存*/ new.this = MY_MALLOC(sizeof(s_servo)); if(NULL == new.this){ return new; } memset(new.this,0,sizeof(s_servo)); /*初始化 SERVO 对象的私有成员*/ ((s_servo*)new.this)->xId = xId; ((s_servo*)new.this)->xChn = xChn; /*初始化 SERVO 对象的公有接口*/ new.set = servo_set_angle; /*初始化 SERVO 对象用到的定时器*/ ret = my_timer.pwm_init(xId, 7199, 199, xChn); if(ret != R_OK) {new.this = NULL; return new;} my_timer.pwm_set(xId, xChn, 0); if(ret != R_OK) {new.this = NULL; return new;} return new; } /* Private Functions -------------------------------------------------------------------*/ static int servo_set_angle(const c_servo* p_obj, float angle) { s_servo* this = NULL; /*检查参数*/ if(NULL == p_obj || NULL == p_obj->this || angle < 0.0f || angle > 180.0f) { return R_ERROR; } this = p_obj->this; /* 周期 20ms = 200 0.5ms = 0° = 5 1.5ms = 90° = 15 2.5ms = 180° = 25 */ uint16_t pul = angle / 180.0f * 20.0f + 5.0f; my_timer.pwm_set(this->xId, this->xChn, pul); return R_OK; } static int servo_set_angle_360(const c_servo* p_obj, float speed_and_direction) { s_servo* this = NULL; // 参数有效性检测 if (NULL == p_obj || NULL == p_obj->this || speed_and_direction < -1.0f || speed_and_direction > 1.0f) { return R_ERROR; } this = p_obj->this; /* 映射规则解释: [-1.0, 1.0] 表示从全速逆时针到全速顺时针的速度区间。 中间点 0 表示停止运动。 新增映射关系: -1 -> 5% (最大逆时针) 0 -> 7.5%(静止不动) +1 -> 10%(最大顺时针) */ const float min_duty_cycle = 5.0f; // 最小占空比 (%) const float max_duty_cycle = 10.0f; // 最大占空比 (%) const float neutral_duty_cycle = 7.5f; // 中立位置 (%) // 将输入的速度/方向参数转换为相应的占空比 float duty_cycle = neutral_duty_cycle + (speed_and_direction * (max_duty_cycle - neutral_duty_cycle)); // 设置具体的 PWM 输出 my_timer.pwm_set(this->xId, this->xChn, duty_cycle); return R_OK; } #endif /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 解释一下这段代码
最新发布
05-13
### C语言 `memset` 函数的使用方法、作用及示例 #### 1. **函数定义** `memset` 是 C 语言标准库 `<string.h>` 中的一个函数,用于将指定内存区域的内容设置为某个特定值。它的函数原型如下: ```c void *memset(void *ptr, int value, size_t num); ``` - `ptr`: 指向要填充的内存块的指针。 - `value`: 要设置的值,以整数形式表示,但实际上会被解释为无符号字符(即只取低8位)。 - `num`: 需要被设置的字节数。 此函数返回指向同一内存块的指针[^2]。 --- #### 2. **主要作用** `memset` 主要用来快速初始化一段连续的内存空间,常用于以下场景: - 初始化数组或结构体的所有成员为固定值(通常是0或-1)。 - 清除动态分配的内存内容。 - 设置缓冲区为某种特殊标志值以便后续处理。 通过这种方式可以简化代码逻辑并提高程序性能[^4]。 --- #### 3. **典型应用场景** ##### (1) 数组清零 当需要把一个整型数组的所有元素都设为0时,可以用下面的方法实现: ```c #include <stdio.h> #include <string.h> int main() { int arr[5]; memset(arr, 0, sizeof(arr)); for(int i=0;i<5;i++) { printf("%d ", arr[i]); } } // 输出结果:0 0 0 0 0 ``` 此处调用了 `memset`, 将长度为 `sizeof(arr)` 字节范围内的每一个字节均赋值成数值'0'.由于每个整形变量占据四个字节,在本例子中正好使得五个整数都被置成了零[^4]. --- ##### (2) 结构体重置 对于复杂的结构体实例来说,手动逐一设定各个字段非常繁琐而且容易出错。此时就可以采用全局重置的办法: ```c typedef struct { int id; char name[20]; float salary; } Employee; Employee emp; memset(&emp, 0, sizeof(Employee)); printf("ID=%d\nName=%s\nSalary=%.2f", emp.id, emp.name, emp.salary); /* Output will be something like this depending on system encoding etc. ID=0 Name= Salary=0.00 */ ``` 在这我们将整个 employee 实例所占存储单元的每一位二进制位都改写成了代表‘空白’状态的数据模式[^1]. --- ##### (3) 动态分配内存清理 假如我们申请了一片新的堆上空间准备存放字符串或者其他任何形式的信息之前最好先把它打扫干净再投入使用: ```c char* buffer = malloc(100); if(buffer != NULL){ memset(buffer , '\0', 100); /* Fill with null characters */ free(buffer ); } ``` 这样做的好处在于防止未预期的行为发生比如读取到了残留垃圾数据等问题[^5]. --- #### 4. **注意事项** 尽管 `memset` 很强大也很方便,但在实际编码过程中仍需谨慎对待以下几个方面: - 只能按字节单位操作因此如果试图用它去改变非单字节类型的对象则可能导致意想不到的结果; - 如果传入错误参数例如超出有效边界或者负尺寸都会引发不可预测后果甚至崩溃应用程序运行环境; - 不适用于含有指针成员的复合类型因为简单地把这些地址位置抹掉等于丢失了它们原本指向的目标实体链接关系[^3]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值