使用宏时C结构初始化问题的数组

时间:2014-02-04 12:26:32

标签: c arrays macros struct

为什么adsafe_tags [1]未正确初始化?

// local string (via static)
#define SSTRL(varname, val) \
    static const char varname[] = val

#define SSTRLEN(var) \
    (sizeof(var) - 1)

struct scs_data_tag
{
    uint16_t key_size;
    uint16_t val_size;
    char     data[];
};

SSTRL(ADSAFE_KEY, "p.as.rsa");
SSTRL(ADSAFE_VAL_BAD, "0");
SSTRL(ADSAFE_VAL_GOOD, "1000");
#define ADSAFE_KV_BAD "p.as.rsa0"
#define ADSAFE_KV_GOOD "p.as.rsa1000"

struct scs_data_tag adsafe_tags[] = {
    {SSTRLEN(ADSAFE_KEY), SSTRLEN(ADSAFE_VAL_BAD), ADSAFE_KV_BAD},
    {SSTRLEN(ADSAFE_KEY), SSTRLEN(ADSAFE_VAL_GOOD), ADSAFE_KV_GOOD}
};

在gdb中我得到了这个:

(gdb) p adsafe_tags
$7 = {{key_size = 8, val_size = 1, data = 0x8ce664 <adsafe_tags+4> "p.as.rsa0"}, {key_size = 11888, val_size = 29537, data = 0x8ce668 ".rsa0"}}

2 个答案:

答案 0 :(得分:2)

您尚未指定data struct scs_data_tag成员的大小。这声明了C99 flexible array member。默认情况下,此成员的大小为0,并且您需要malloc以上的实际结构大小才能包含数据。

根据标准,struct scs_data_tag不可能是数组的元素(因为它包含一个灵活的数组成员)。但是一些编译器支持这作为扩展。

如果你改为给这个数组足够大(例如char data[40]),那么你的代码应该可以工作。

答案 1 :(得分:1)

添加到 interjay 的答案。您看到adsafe_tags[1].key_size = 11888以十六进制为0x2e70,表示ASCII字符p(= 0x70)和.(= 0x2e),因此"p."

同样,adsafe_tags[1].val_size = 295370x7361"as",其余值正确打印为字符串。

这表明没有空间分配给adsafe_tags[0].data

您提供的用于初始化它的字符串已映射到下一个数据集。