【问题标题】:what should strlen() really return in this code?strlen() 应该在这段代码中真正返回什么?
【发布时间】:2015-08-17 13:56:28
【问题描述】:
#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。)

【问题讨论】:

  • 注意:strlen() 返回size_t,所以你应该使用%zu 格式说明符。
  • 同样的事情 sizeof 运算符使用 s%zu 而不是 %d 或 %ld 因为 long unsigned int
  • 它可以打印任何东西。 strlen() 会很高兴地继续在内存中移动,直到找到一个 0。它恰好在 15 个字节中找到一个。

标签: c sizeof strlen


【解决方案1】:

在您的代码中

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

qq 没有资格被称为 字符串,因为它不是以空值结尾的。所以打电话给strlen() wilh qq 是在招惹麻烦。

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

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

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

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


心情轻松一点,回答一下

strlen() 应该在这段代码中真正返回什么?

如果我说,“尊敬的印度总统的电话号码”,嗯,从技术上讲,我可能是正确的!

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

【讨论】:

    【解决方案2】:

    您的字符串不是以空值结尾的。这意味着您的代码不是确定性的。 strlen() 将在遇到\0(空字节/字符)时终止;由于在遇到\0 之前的顺序扫描,结果可能会有所不同。

    【讨论】:

      【解决方案3】:

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

      字符串是null terminated in c

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

      【讨论】:

        【解决方案4】:

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

        因为qq 中没有\0strlen继续进入其他不相关的内存。最终,它偶然遇到了一个\0 字节。

        对你来说显然是在 15 个字节之后(或超过 qq 末尾的 11 个字节)。
        但这不是确定性或保证的,而且非常不安全。
        strlen 很可能会在碰巧找到 \0 字符之前尝试读取无效内存,在这种情况下,您的程序将出现段错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          相关资源
          最近更新 更多