繁体   English   中英

C ++:sizeof用于数组长度

[英]C++: sizeof for array length

假设我有一个名为LengthOf(array)的宏:

sizeof array / sizeof array[0]

当我制作一个新的大小为23的数组时,是否应该为LengthOf取回23?

WCHAR* str = new WCHAR[23];
str[22] = '\0';
size_t len = LengthOf(str); // len == 4

为什么len == 4

更新 :我打错了,是WCHAR* ,而不是WCHAR**

因为这里的str是指向指针的指针,而不是数组。

这是指针和数组之间的细微差别之一:在这种情况下, 指针位于堆栈上,指向已分配给其他位置(可能是堆)的23个字符的数组。

WCHAR** str = new WCHAR[23];

首先,这甚至不应该编译-它尝试将pointer to WCHARpointer to pointer to WCHAR分配给pointer to WCHARpointer to pointer to WCHAR 编译器应基于此不匹配拒绝代码。

其次, sizeof(array)/sizeof(array[0])宏的已知缺点之一是,当应用于指针而不是实际数组时,它可能并且将完全失败。 在C ++中,您可以使用模板来获取拒绝的代码:

#include <iostream>

template <class T, size_t N>
size_t size(T (&x)[N]) { 
    return N;
}

int main() { 
    int a[4];
    int *b;

    b = ::new int[20];

    std::cout << size(a);      // compiles and prints '4'
//    std::cout << size(b);    // uncomment this, and the code won't compile.
    return 0;
}

正如其他人指出的那样,如果将指针而不是实际数组传递给宏,则宏将无法正常工作。 不幸的是,由于大多数表达式中的指针和数组的计算结果相似,除非您使宏变得更加复杂,否则编译器无法让您知道存在问题。

有关类型安全的C ++版本宏(如果传递指针而不是数组类型,将生成错误),请参见:

它不能完全“解决”您的问题,但可以让您知道您做错了什么。

对于在C中工作并且更安全的宏(许多指针将诊断为错误,但不幸的是,某些指针将通过而不会出错-包括您的指针):

当然,使用#ifdef __cplusplus您既可以在通用标头中使用它,也可以让编译器为C ++构建选择较安全的标头,而在C ++无效时选择与C兼容的标头。

问题是sizeof运算符检查其参数的大小。 您的示例代码中传递的参数是WCHAR* 因此,sizeof(WCHAR *)为4。如果您有一个数组,例如WCHAR foo[23] ,并且采用sizeof(foo) ,则传递的类型实质上是WCHAR[23] ,并且将产生sizeof(WCHAR) * 23 实际上,在编译类型上, WCHAR*WCHAR[23]是不同的类型,尽管您和我可以看到new WCHAR[23]的结果在功能上等效于WCHAR[23] ,但实际上,返回类型是WCHAR* ,绝对没有尺寸信息。

作为核心,由于您的平台上的sizeof(new WCHAR[23])等于4,因此您显然要处理的指针为4个字节的体系结构。 如果是在x64平台上构建的,则会发现sizeof(new WCHAR[23])将返回8。

你写了:

WCHAR* str = new WCHAR[23];

如果23是一个静态值(在程序的整个生命周期中都不是变量),则最好使用#define或const而不是仅对 23进行硬编码

#define STR_LENGTH 23
WCHAR* str = new WCHAR[STR_LENGTH];
size_t len = (size_t) STR_LENGTH;

或C ++版本

const int STR_LENGTH = 23;
WCHAR* str = new WCHAR[STR_LENGTH];
size_t len = static_cast<size_t>(STR_LENGTH);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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