[英]C conventions - how to use memset on array field of a struct
I wold like to settle an argument about proper usage of memset when zeroing an array field in a struct (language is C). 在将结构中的数组字段归零(语言为C)时,我想解决关于正确使用memset的争论。
Let say that we have the following struct: 假设我们有以下结构:
struct my_struct {
int a[10]
}
Which of the following implementations are more correct ? 以下哪个实现更正确?
Option 1: 选项1:
void f (struct my_struct * ptr) {
memset(&ptr->a, 0, sizeof(p->a));
}
Option 2: 选项2:
void f (struct my_struct * ptr) {
memset(ptr->a, 0, sizeof(p->a));
}
Notes: 笔记:
If the field was of a primitive type or another struct (such as 'int') option 2 would not work, and if it was a pointer (int *) option 1 would not work. 如果字段是基本类型或另一个结构 (例如'int'),则选项2将不起作用,如果它是指针(int *),则选项1将不起作用。
Please advise, 请指教,
For a non-compound type, you would not use memset
at all, because direct assignment would be easier and potentially faster. 对于非复合类型,您根本不会使用
memset
,因为直接赋值会更容易且可能更快。 It would also allow for compiler optimizations a function call does not. 它还允许函数调用不进行编译器优化。
For arrays, variant 2 works, because an array is implictily converted to a pointer for most operations. 对于数组,变体2可以工作,因为对于大多数操作,数组被有意地转换为指针。
For pointers, note that in variant 2 the value of the pointer is used, not the pointer itself, while for an array, a pointer to the array is used. 为指针,请注意,在变体2中的指针的值时,不指针本身,而对于一个阵列中,使用一个指针数组 。
Variant 1 yields the address of the object itself. 变体1产生对象本身的地址。 For a pointer, that is that of the pointer (if this "works" depends on your intention), for an array, it is that of the array - which happens to always be the address of its first element - but the type differs here (irrelevant, as
memset
takes void *
and internally converts to char *
). 对于指针,即指针的指针(如果这“工作”取决于你的意图),对于数组,它是数组的指针 - 它恰好总是第一个元素的地址 - 但这里的类型不同(无关紧要,因为
memset
采用void *
并在内部转换为char *
)。
So: it depends; 所以:这取决于; for an array, I do not see much difference actually, except the address-operator might confuse reads not so familar with operator preceedence (and it is more to type).
对于一个数组,我实际上没有看到太大的区别,除了地址运算符可能会混淆不那么熟悉的运算符优先级(并且更多的是键入)。 As a personal opinion: I prefer the simpler syntax, but would not complain about the other.
作为个人意见:我更喜欢更简单的语法,但不会抱怨另一个。
Note that memset
with any other value than 0
does not make much sense actually; 请注意,任何其他值不超过
0
memset
实际上没有多大意义; it might not even guarantee an array of pointers to be interpreted as null pointer . 它甚至可能不能保证一个指针数组被解释为空指针 。
IMO, option 1 is preferable because the same pattern works for any object, not just arrays: IMO,选项1是首选,因为相同的模式适用于任何对象,而不仅仅是数组:
memset(&obj, 0, sizeof obj);
You can tell just from this statement that it does not cause a buffer overflow -- ie does not access out of bounds. 你可以从这个语句中断言它不会导致缓冲区溢出 - 即不会访问越界。 It's still possible that this doesn't do what was intended (eg if
obj
is a pointer and it was intended to set what the pointer was pointing to), but at least the damage is contained. 它仍然可能不会达到预期的效果(例如,如果
obj
是一个指针,它的目的是设置指针指向的内容),但至少包含了损坏。
However if you accidentally use memset(p, 0, sizeof p)
on a pointer then you may write past the end of the object being pointed to; 但是,如果您不小心在指针上使用
memset(p, 0, sizeof p)
,那么您可以写入指向的对象的末尾; or if the object is bigger than sizeof p
, you leave the object in a weird state. 或者如果对象大于
sizeof p
,则将对象置于奇怪的状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.