sizeof静态数组成员返回指针的大小而不是数组

时间:2014-02-03 12:02:37

标签: c++ sizeof arrays static-array

所以我有一个C ++结构,它有一个静态数组作为成员,我想在构造函数中询问它的大小。正如我从本文http://msdn.microsoft.com/en-us/library/4s7x1k91(VS.71).aspx中所理解的那样,sizeof可以应用于静态数组,以查找整个数组的大小(以字节为单位),而不仅仅是它的类型。但是,当我对成员执行sizeof()时,它给出了4(指针的大小)而不是数组的大小。这是上下文(平凡的):

struct A
{
    char descirption[128];
    int value;

    A(const char desc[], int val)
    {
        size_t charsToCopy = std::min(sizeof(description), sizeof(desc));
        memcpy(description, desc, charsToCopy);
        value = val;
    }
}

int main()
{
    A instance("A description string", 1);
    //now instance has a description string that says "A des" followed by garbage characters
}

那么如何获得成员char数组的大小?

修改

当我在编译器中放置一个断点并检查两个值sizeof(description)sizeof(desc)时,我看到sizeof(description) == 4sizeof(desc) == 21。因此我的困惑。因为我正在将一个字符串文字传递给构造函数,所以编译器似乎很高兴告诉我传入的字符串的实际大小。如果我将它分配给某个地方的某个变量,可能就不会这样了,但是现在我我试图追查根本问题:sizeof(some-member-static-array)给了我一些(相对)毫无意义的东西。

sizeof是否有可能进行某种字符串长度测量,因为它是一个字符数组?

3 个答案:

答案 0 :(得分:5)

尽管有语法,但您无法通过值将数组传递给函数。它衰减到指针,无法找到大小;你的功能相当于

A(const char * desc, int val)

以便sizeof(desc)是指针的大小。

您可以通过引用传递数组,通过数组的大小模板化函数:

template <size_t desc_size>
A(const char (&desc)[desc_size], int val)

size参数将从函数参数自动推断,因此传递字符串文字的代码将按原样运行。

但是,这仅在参数确实是已知大小的数组时才有效;如果你想处理更一般的字符串,那么你需要更复杂的东西。通常,使用std::string来管理字符串会更方便 - 它会自动处理内存,并为您跟踪大小。

答案 1 :(得分:2)

这不是给你4个大小的成员,而是这个论点。 C ++中的数组类型参数转换为指针,因此构造函数等效于:

A(const char *desc, int val)

这就是你获得指针大小的原因。如果你真的想使用memcpy,你必须将数组的长度传递给构造函数。另一种方法是使用strncpy,最大字符数设置为128。

当然,如果您使用std::string,则不会出现此问题。

答案 2 :(得分:0)

在此构造函数中

A(const char desc[], int val)
{
    size_t charsToCopy = std::min(sizeof(description), sizeof(desc));
    memcpy(description, desc, charsToCopy);
    value = val;
}

参数desc由编译器隐式转换为指向其第一个字符的指针。当您使用函数std :: min时,很明显sizeof(const char *)小于sizeof(description),并且只要指针的大小等于4,函数将始终返回4.

此外,在调用memcpy之后,可能会发生结果字符串不包含终止零。我将按以下方式定义构造函数

A(const char desc[], int val)
{
    strncpy(description, desc, 128);
    description[127] = '\0';
    value = val;
}

使用enymerator或静态常量定义幻数128的名称也是一个好主意。

或者至少你可以写下面的方式

A(const char desc[], int val)
{
    const size_t N = sizeof( description );
    strncpy(description, desc, N);
    description[N-1] = '\0';
    value = val;
}