繁体   English   中英

为什么当数组不包含空终止符时 strlen() 返回奇怪的结果?

[英]Why does strlen() return strange result when array doesn't contain null terminator?

我有两个程序。 两者都从字符串文字初始化数组。 在一种情况下,数组大小正好是我想放入数组中的字符数。

我想知道为什么两个程序的strlen()返回的大小输出不同。 是因为缺少终止空字符吗? 如果是这样,那么为什么输出是 16?

#include<stdio.h>
#include<string.h>
main()
{
    char str[5] = "ankit";
    printf("size of = %d \n ",sizeof(str));
    int len = strlen(str);
    printf("length = %d \n ",len);
}

输出:-大小= 5,长度= 16

#include<stdio.h>
#include<string.h>
main()
{
    char str[] = "ankit";
    printf("size of = %d \n ",sizeof(str));
    int len = strlen(str);
    printf("length = %d \n ",len);
}

输出:-大小= 6,长度= 5

在您的第一个代码中,通过编写

 char str[5] = "ankit";

您没有任何空间可用于存储空终止符,这是str用作string所必需的。 因此,在这种情况下, strlen()通过溢出分配的内存以搜索空终止符来调用未定义的行为

OTOH,在第二个片段中,

char str[] = "ankit";

您将大小分配留给编译器,它为用作初始值设定项的字符串文字中的元素以及空终止符分配内存。 所以,你得到了想要的结果。

IMO,总是用后面的方法,省时省力不少。

您的char[5]太短,无法容纳值"ankit"

正如您自己所说,C 样式字符串的末尾有\\0终止符。 这意味着,您的字符串文字实际上在内部表示为"ankit\\0" (其中 \\0 是单个字符)。

由于strlen()函数找不到\\0字符,因此它的行为未定义。

这意味着,您需要一个char[6]来表示您的字符串。
通过省略数组的显式长度,您可以让编译器选择大小(通过初始化,在编译时已知)。 因此,编译器分配正确的大小(6 个字符)。

是的,这是因为第一个示例中的数组没有为 0 终止符留出足够的空间。 以下是strlen基本工作原理:

size_t strlen( const char *str )
{
  size_t len = 0;
  while( *str++ )
    len++;
  return len;
}

strlenstr中第一个元素的地址开始,并“沿着”连续地址向下走,直到它看到一个0字节。 由于strlen不知道对应于str的数组实际上有多大(它得到的只是一个指向第一个元素的指针),它会继续越过数组的末尾,直到看到0

所有字符串都是char数组,但并非所有char数组都是字符串; 如果没有零终止符,则它不是字符串。

char str[5]最多可以包含 4 个字符,最后一个额外字节应保留给 '\\0' 字符。 因此它的未定义行为。

暂无
暂无

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

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