所以我有一个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) == 4
和sizeof(desc) == 21
。因此我的困惑。因为我正在将一个字符串文字传递给构造函数,所以编译器似乎很高兴告诉我传入的字符串的实际大小。如果我将它分配给某个地方的某个变量,可能就不会这样了,但是现在我我试图追查根本问题:sizeof(some-member-static-array)给了我一些(相对)毫无意义的东西。
sizeof是否有可能进行某种字符串长度测量,因为它是一个字符数组?
答案 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;
}