繁体   English   中英

C约定 - 如何在struct的数组字段上使用memset

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM