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

时间:2015-11-26 12:21:42

标签: c arrays string

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

我想知道为什么strlen()返回的大小输出对于两个prorgams都不同。是因为缺少终止空字符?如果是这样,那么为什么输出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

4 个答案:

答案 0 :(得分:5)

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

str

您没有剩余空间来存储空终结器,这需要char str[] = "ankit"; 用作字符串。因此,在这种情况下,happens to be a subclass通过超出分配的内存来搜索空终止符来调用strlen()

OTOH,在第二个片段中,

{{1}}

将大小分配留给编译器,并为用作初始化器和空终止符的字符串文字中的元素分配内存。所以,你得到了理想的结果。

IMO,总是使用后来的方法,不时省去很多头痛。

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:0)

char str[5]最多需要4个字符,最后一个额外字节应保留为&#39; \ 0&#39;字符。因此它的未定义行为。

答案 3 :(得分:0)

是的,这是因为第一个示例中的数组没有为0终止符留出足够的空间。以下是strlen基本上如何运作的方式:

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

strlenstr中第一个元素的地址开始,然后“遍历”连续的地址,直到它看到一个0值的字节。由于strlen不知道与str对应的数组实际上有多大(它只是指向第一个元素的指针),它将继续超过数组的末尾,直到它看到0

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