c - 发送参数地址是否安全?
问题描述
考虑以下代码片段:
void read_write(unsigned* ptr, bool r_or_w) {
if (r_or_w) {
*ptr = read_from_device_register();
} else {
write_to_device_register(*ptr);
}
}
unsigned read(void) {
unsigned data = 0;
read_write(&data, 1);
return data;
}
void write(unsigned data) {
read_write(&data, 0); // <--- sending address of received argument
}
具体来说,考虑void write(unsigned data)
发送一个指向它作为参数接收的值的指针的事实。
比较:
void write(unsigned w_data) {
unsigned data = w_data;
read_write(&data, 0); // <--- sending address of local variable
}
在这两种情况下data
都存储在堆栈中,只有在第一种情况下data
存储在调用者的调用帧中,而不是作为局部变量存储在被调用者中。安全吗?有什么陷阱吗?如果有的话,它有多普遍?
解决方案
这里的生命周期没有问题,只要read_write
不将指针存储在可以比框架中的指针data
寿命write
更长的地方。因此,从程序正确性的角度来看,这是安全的。事实上,给定的两个选项之间没有区别——传入参数的地址可以像获取局部变量的地址一样被获取。至于在write
's 调用者的框架中修改变量的问题,这也无关紧要 -data
是按值传递的。
但是,如果经常调用函数或在紧密循环中调用函数,则无符号整数的指针间接可能会产生很大的开销。
此外,从设计的角度来看,这似乎是一个笨拙的设计,有点难以阅读。最终委托给的write
代表。直观地遵循这有点尴尬,并且不必要地将读取和写入路径混合在一起只是为了让它们再次发散;这可能是不安全的,因为与更简单的设计相比,代码更脆弱且更容易维护错误。read_write
write_to_device_register
推荐阅读
- php - 在 Woocommerce 中访问受保护的属性 WC_Product_Variation::$id
- reactjs - React - Material-UI Modal 导致 tabindex 出错
- javascript - 使元素显示在轮播上方
- php - Symfony4 - 如何更新学说 ArrayCollection ?
- node.js - Nodejs中带有“progress”模块的堆叠进度条
- amazon-web-services - 如何直接在s3上解压s3上的文件?
- html - 强制css中的高度
- netsuite - 如何通过 WSDL 更新 NetSuite Department isInactive?
- javascript - 如何将 HTML 画布作为图像发送?
- spring-mvc - 如何在 thymeleaf 和 Spring MVC 中使用输入单选按钮