【问题标题】:initializing a structure array using memset使用 memset 初始化结构体数组
【发布时间】:2011-03-24 07:11:14
【问题描述】:

gcc 4.4.4 c89

我有以下结构。

struct device_sys
{
    char device[STRING_SIZE];
    int id;
    char category;
};

int main(void)
{
    struct device_sys dev_sys[NUM_DEVICES];

    memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(dev_sys));

    return 0; 
}

当我调用 memset 时,我得到一个堆栈转储。这不是初始化结构体数组的正确方法吗?

【问题讨论】:

  • 如果你 typedef struct device_sys 到 dev_sys,你可以保留你提到的 memset。 typedef struct device_sys dev_sys; memset(dev_sys, 0, NUM_DEVICES * sizeof(dev_sys));

标签: c memset


【解决方案1】:

要么

memset(&dev_sys, 0, sizeof dev_sys);

memset(dev_sys, 0, NUM_DEVICES * sizeof(struct device_sys));

或者,如果你愿意的话

memset(dev_sys, 0, NUM_DEVICES * sizeof *dev_sys);

但不是你原来的变种。

请注意,在所有变体的特定情况下,您可以使用&dev_sysdev_sys 作为第一个参数。效果将是相同的。但是,&dev_sys 在第一个变体中更合适,因为 if 遵循 memset(ptr-to-object, object-size) 成语。在第二个和第三个变体中,使用dev_sys(或&dev_sys[0])更合适,因为它遵循memset(ptr-to-first-element, number-of-elements * element-size) 成语。

P.S.当然,不要使用所有那些骇人听闻的memset 诡计,在您的特定情况下,您应该使用初始化器声明您的数组

struct device_sys dev_sys[NUM_DEVICES] = { 0 };

不需要memset

【讨论】:

  • OP 说的是 c89,那不是初始化器 c99 吗?
  • @bstpierre:没有。为什么?聚合初始化器从一开始就在 C 中(嗯,几乎)。
  • 作为您的第一个示例。 &dev_sys。那不是(的地址)。就像实际指针的地址一样。 dev_sys 已经在指针处。如果我声明了这样的 struct device *dev_sys.对于第一个参数,我将发送指针 dev_sys。谢谢
  • @robUK: dev_sys 不是指针,dev_sys 是一个数组。虽然在某些情况下它可能“假装”为指针,但它并不是真正的指针。 &dev_sys 给你一个指向整个数组的指针,它在数值上与指向它的第一个元素的指针相同(这反过来就是为什么你可以使用任何一个来获得相同的效果)。如果您将其声明为struct device *dev_sys(指针),&dev_sys 将不起作用。但是当它被声明为一个实际的数组(如在您的 OP 中)时,&dev_sys 将起作用。
  • @AnT 你是对的。这个例子绝对正确。我已经比较了你和我的代码。我的印象是,您的第一个示例依赖于编译器。就我而言,我使用了太旧的 gcc 版本。
【解决方案2】:

您的代码中有错字。修复:

memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(struct device_sys));

选择好名字可以避免一半的错误。我会推荐“设备”。

【讨论】:

  • 可能更安全的方式:memset(dev_sys, 0, sizeof(dev_sys));
【解决方案3】:

您必须将类型而不是变量传递给sizeof 运算符。

memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(struct device_sys));

我更喜欢使用typedef 作为结构体。

typedef struct tag_device_sys
{
    char device[STRING_SIZE];
    int id;
    char category;
} device_sys;

你可以使用memset如下:

    memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(device_sys));

【讨论】:

    【解决方案4】:

    对于数组,sizeof 为您获取数组的整个大小,而不是单个元素的大小。 sizeof 运算符是少数几个不将数组视为指向其第一个元素的指针的地方之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 2010-11-05
      相关资源
      最近更新 更多