Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ VisualC+中的sizeof(“…”)+;让我不高兴_C++_Visual C++_Sizeof - Fatal编程技术网

C++ VisualC+中的sizeof(“…”)+;让我不高兴

C++ VisualC+中的sizeof(“…”)+;让我不高兴,c++,visual-c++,sizeof,C++,Visual C++,Sizeof,我正在编写一段代码,其中我使用sizeof(“somestring”)作为函数的参数,然后我注意到函数没有返回预期值,所以我去查看相应的asm代码,发现了一个令人不快的惊喜。有人对此有解释吗(见图) 我知道有1000多种不同的方法可以做到这一点,我已经实现了其中的另一种,但我确实想知道这种行为背后的原因 好奇的是,这是Visual Studio 2008 SP1。在每个C字符串的末尾都有一个C字符串终止符“\0”,因此“pdfa”实际上是以下字符数组{'p'、'd'、'f'、'a'、'\0'}

我正在编写一段代码,其中我使用
sizeof(“somestring”)
作为函数的参数,然后我注意到函数没有返回预期值,所以我去查看相应的asm代码,发现了一个令人不快的惊喜。有人对此有解释吗(见图)

我知道有1000多种不同的方法可以做到这一点,我已经实现了其中的另一种,但我确实想知道这种行为背后的原因


好奇的是,这是Visual Studio 2008 SP1。

在每个C字符串的末尾都有一个C字符串终止符“\0”,因此“pdfa”实际上是以下字符数组
{'p'、'd'、'f'、'a'、'\0'}
,但不会打印\0。改用strlen(“pdfa”)。

值5是正确的。该常数包括零终止符字节。“监视”窗口中4的显示似乎不正确。

字符串文字类型为“n
常量字符数组”([lex.String],^8),其中n是组成字符串的
字符数。由于字符串以null结尾,
sizeof
将返回“正常”字符数加1;watch窗口是错误的,它可能是一个bug(正如@Gene Bushuyev所说,它可能将其解释为指针,而不是literal=数组)


值5嵌入到代码中这一事实是正常的,它是编译时运算符的大小。

请记住,C字符串包含一个结尾为零的
\0
。5是正确的值。

那么,5是sizeof(“PDFA”)的正确值。4个字符+尾随零

此外,请记住,“结果不一定与通过添加单个成员的存储要求计算的大小相对应。/Zp编译器选项和pack pragma会影响成员的对齐边界。”


说到Watch窗口,我认为它只是显示指针(constchar*)本身的大小。尝试在64位模式下重新编译程序,然后检查监视窗口将显示什么。如果我是对的,那么你将看到8。事情出错的原因™ 这里是您选择的抽象级别太低,
memcmp

再上一层你就有了strcmp
和wcscmp

在这一级别的基础上,您有
std::string
std::wstring

您选择的最低抽象级别的“速度”(哈!)被

  • 结果不正确

  • 由于缺乏类型知识(宽字符串或窄字符串,您的代码不知道)而导致效率低下

  • 由于缺乏数据知识(大写或小写),效率低下

与其把时间浪费在解决低效的最低级别代码的问题上,也不要把时间浪费在找出低级别工具令人费解的细节上,不如使用更高、更安全的抽象级别。
请注意,
sizeof(“abcd”)
是5。正如汉斯·帕桑(Hans Passant)所说,手表窗口可能显示指针的大小。但是,我不同意Hans的观点,即调试器通常无法知道数组的大小:对于调试构建,它可以知道原始源的任何内容,包括需要时的逐字原始源(并且在上下文中显示该逐字原始源)。所以,这4是一个错误的一种方式或其他。调试器代码中的错误或其设计中的错误


Cheers&hth.,

Sizeof是一个运算符,其计算结果为大小t,在32位平台上通常为无符号整数。这就是为什么在调试器中将其视为4。sizeof运算符也是一个右值,因此不能在内存上设置观察点。如果可以,该位置将包含5个。字符串加终止符的大小。

在第2行显示的asm代码中,它推送字符串“PDFA”的偏移量,不是第一个
memcmp
的偏移量吗?您是否复制粘贴了正确的asm代码?我确信同样的问题也会发生,但您的图像是错误的VC10在评估watch视图中指针和/或引用的表达式时经常出错。这在以前的版本中没有发生。您正在使用VC10吗?
sizeof(“数据”)
是5个字节,计算数组的最后0。我怀疑检查器将其实现为函数调用,并将char文本转换为指向char的指针,从而得到答案4。调试器!=编译器。您可以在调试器中获得指针的大小。调试器通常无法知道数组的大小。要检查调试器是否将字符串解释为指针,只需向字符串中添加任意数量的字符,这样字符串的长度就不会与指针的大小不一致(例如,使字符串
“pdfa123123”
)那么手表窗口中的
4
呢?@MooingDuck:可能是个bug;我支持Gene的观点,即它被解释为指针(而不是数组),从而给出4个字节(32位)的结果。打包不适用于此,因为字符串文字不是结构。我更喜欢保留MSDN中的引用。要查看监视窗口是否显示指针的大小,只需检查
sizeof(“pdfa”)是否
sizeof(“pdfaALSDALSDAS”)
具有相同的值。是的。5对4个字符似乎达到了边界条件,字符串的长度和指针的大小非常相似:)