[英]C conventions - how to use memset on array field of a struct
在将结构中的数组字段归零(语言为C)时,我想解决关于正确使用memset的争论。
假设我们有以下结构:
struct my_struct {
int a[10]
}
以下哪个实现更正确?
选项1:
void f (struct my_struct * ptr) {
memset(&ptr->a, 0, sizeof(p->a));
}
选项2:
void f (struct my_struct * ptr) {
memset(ptr->a, 0, sizeof(p->a));
}
笔记:
如果字段是基本类型或另一个结构 (例如'int'),则选项2将不起作用,如果它是指针(int *),则选项1将不起作用。
请指教,
对于非复合类型,您根本不会使用memset
,因为直接赋值会更容易且可能更快。 它还允许函数调用不进行编译器优化。
对于数组,变体2可以工作,因为对于大多数操作,数组被有意地转换为指针。
为指针,请注意,在变体2中的指针的值时,不指针本身,而对于一个阵列中,使用一个指针数组 。
变体1产生对象本身的地址。 对于指针,即指针的指针(如果这“工作”取决于你的意图),对于数组,它是数组的指针 - 它恰好总是第一个元素的地址 - 但这里的类型不同(无关紧要,因为memset
采用void *
并在内部转换为char *
)。
所以:这取决于; 对于一个数组,我实际上没有看到太大的区别,除了地址运算符可能会混淆不那么熟悉的运算符优先级(并且更多的是键入)。 作为个人意见:我更喜欢更简单的语法,但不会抱怨另一个。
请注意,任何其他值不超过0
memset
实际上没有多大意义; 它甚至可能不能保证一个指针数组被解释为空指针 。
IMO,选项1是首选,因为相同的模式适用于任何对象,而不仅仅是数组:
memset(&obj, 0, sizeof obj);
你可以从这个语句中断言它不会导致缓冲区溢出 - 即不会访问越界。 它仍然可能不会达到预期的效果(例如,如果obj
是一个指针,它的目的是设置指针指向的内容),但至少包含了损坏。
但是,如果您不小心在指针上使用memset(p, 0, sizeof p)
,那么您可以写入指向的对象的末尾; 或者如果对象大于sizeof p
,则将对象置于奇怪的状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.