一个以空字符结尾的const char*的sizeof运算符

22
const char* a;

如何确保字符串'a'以空字符结尾?当a = "abcd"且使用sizeof(a)时,结果为4。这是否意味着它没有以空字符结尾?如果是的话,我会得到5吗?

6个回答

34

sizeof(a) 返回的是指针的大小,而非指针所指向的字符数组的大小。这和使用 sizeof(char*) 的效果相同。

您需要使用 strlen() 来计算以 null 结尾的字符串的长度(请注意,返回的长度包括 null 终止符,因此 strlen("abcd") 是 4,而不是 5)。或者,您可以使用字符串字面值初始化一个数组:

char a[] = "abcd";
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer

字符串字面值 "abcd" 以 null 结尾;所有字符串字面值都以 null 结尾。


1
OP已经在使用const,所以const char a[]char a[]更好。 - aschepler
4
进一步澄清,strlen()函数只能获取字符数组中数据的逻辑长度,而不能获取为其分配的字节数。我认为没有办法获取该数字。 - T.E.D.

12

你得到了4,因为在你的系统上指针大小为4。如果你想获取以null结尾的字符串的长度,你需要使用C标准库中的strlen函数。


strnlen 是特定于平台的函数,不在标准库中。 - jer
6
“strnlen”并没有真正增加安全性,对吗?如果你的函数需要一个以空字符结尾的字符串,但没有得到(或者如果一个函数被指定为返回以空字符结尾的字符串,但没有返回),那么你的代码已经出现了问题。 - James McNellis
1
@James:有些破损的代码会导致崩溃,而有些则会导致缓冲区溢出成为远程根漏洞。我尽量不写这两种,但宁愿写前者也不愿意写后者。 - nmichaels

7
问题在于你混淆了一个编译时操作sizeof()和一个运行时操作字符串长度。当你运行sizeof(a)时,得到4的原因是a是一个指针,而C语言中指针的典型大小是4字节。要获取字符串长度,请使用strlen
对于第二个问题,如何确保字符串以null结尾。唯一确定的方法是自己添加null终止符。只有给定char*,无法100%保证它已正确地以null结尾。必须非常小心地确保生产者和消费者之间的char*合同清楚地规定了由谁终止字符串。

啊...我真笨。但是当我执行strlen(a)时,返回的是4,而我知道a应该是"abcd"(通过gdb调试得知)。 - hari
@hari,4是正确的,因为字符串“abcd”的长度确实是4。但是,变量a的内存需求是strlen(a)+1,以处理空终止符。这是C语言中需要一点时间来适应的部分之一。 - JaredPar
这是因为"abcd"的长度为4。strlen函数不会计算空终止符。 - jer
如果我在使用gdb,如何确保我查看的const char *是以空字符结尾的?我正在执行:a [0] ='a'....a [3] ='d'和a [4] ='\ 0'。这是否意味着它已经以空字符结尾了? - hari

5
如果你被交付一个char数组,该数组可能有null结尾的数据,也可能没有,那么没有好的方法可以进行检查。最好的办法是在特定指定的长度范围内搜索null字符(不是无限制的!)。但是,在未初始化的内存区域中找到0字节的数据并不是一件不寻常的事情。
这是关于C语言字符串标准的许多人不喜欢的方面之一。找到客户端传递给你的字符串的长度是一个O(n)搜索操作,最好的情况下,最坏的情况下会出现段错误。
当然,另一个问题是数组和指针是可以互换的。这意味着array_name + 2与&(array_name[2])相同,sizeof(a)是sizeof(char*)而不是数组的长度。

4

sizeof(a)sizeof(const char*),表示指针的大小。它不受 a 的内容影响。如果要计算长度,可以使用 strlen

此外,所有源代码中的双引号字符串字面量(如"abcd")都会自动添加空字符结尾。


1

sizeof(a) 返回的是 const char *a 的尺寸... 而非它所指向的对象的尺寸。你可以使用 strlen(a) 来获取以空字符结尾的字符串的长度,但需要注意的是,strlen 的结果不包括空字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接