strlen()应该在此代码中返回什么内容?

时间:2015-08-17 13:56:28

标签: c sizeof strlen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
    char qq[] = {'a' , 'b' , 'c' , 'd'};
    char qqq[] = "abcd";
    printf("%d\n" , sizeof qq / sizeof qq[0]); // line A
    printf("%d\n" , strlen(qq)); // line B
    printf("%d\n" , sizeof qqq / sizeof qqq[0]); // line C
    printf("%d\n" , strlen(qqq)); // line D

    system("pause");
    return 0;
}

查看上面的代码。数组qq中有四个元素,数组qqq中有五个元素,其中最后一个是'\0'。所以我理解A行打印4,C行打印5。 D线对我来说还可以。我知道在处理字符串时strlen(qqq)等于"sizeof qqq / sizeof qqq[0] - 1"。但是B行打印15让我感到困惑。为什么? (我使用vs2012。)

4 个答案:

答案 0 :(得分:8)

在您的代码中

  char qq[] = {'a' , 'b' , 'c' , 'd'};

qq没有资格被称为字符串,因为它不是以空值终止的。因此,调用strlen() wilh qq会引发麻烦。

这里实际发生的是,strlen()越过qq中的最后一个有效元素来寻找终止null(实际上是缺失的),因此冒险进入越界内存,它会调用undefined behaviour

解决方案:要使qq成为字符串,您必须自己在初始化列表中添加null-terminator,例如

 char qq[] = {'a' , 'b' , 'c' , 'd', '\0'};

就是说,正如我在评论中已经提到的那样,strlen()返回类型为size_t,您应该使用%zu格式说明符来打印结果。

心情较轻,回答

  

strlen()在此代码中应该返回什么内容?

如果我说,&#34;尊敬的印度总统的电话号码&#34; ,从技术上讲,我可能正确!!

严肃地说,UB的输出是,未定义。

答案 1 :(得分:4)

您的字符串不是以空值终止的。这意味着您的代码不具有确定性。只要遇到strlen()(空字节/字符),\0就会终止;结果可能因顺序扫描而有所不同,直到遇到\0

答案 2 :(得分:3)

strlen()计算字符串的长度,但char qq[] = {'a' , 'b' , 'c' , 'd'};不是字符串。将'Non-String'数据传递给strlen时,会获得未定义的结果。

null terminated中的字符串c

应为char qq[] = {'a' , 'b' , 'c' , 'd','\0'};

答案 3 :(得分:2)

strlen将继续前进,直到找到\0字符,计算沿途有多少个字符。

由于qq中没有\0strlen 继续 进入其他不相关的内存。最终偶然会遇到\0字节。

显然是在15个字节之后(或超出qq结尾的11个字节) 但它不具有确定性或保证,并且非常不安全。很可能strlen最终会在找到{{}之前尝试读取无效内存。 1}}字符,在这种情况下,你的程序会出现seg-fault。