2017-04-11 81 views
0

快速的问题。C++ strlen()初始化字符数组

我找不到为什么一个初始化字符数组返回此值。据我所知,的strlen()函数将只返回字符的数量内的阵列,而不是规模,但为什么它会返回,如果有一个不包含字符?

#include <iostream> 
#include <cstring> 
using namespace std; 

int main() 
{ 
    const int MAX = 50; 

    char test[MAX]; 
    int length = strlen(test); 

    cout << "The current \'character\' length of the test array is: " << length << endl; 
    // returns "61" 
     // why? 

    cin >> test; //input == 'nice' 
    length = strlen(test); 

    cout << "The new \'character\' length of the test array is: " << length << endl; 
// returns 4 when 'nice' is entered.  
// this I understand. 


    return 0; 
} 

这是一个项目中我发疯了,因为我会试图用一个循环来将信息反馈到一个字符数组,但strlen的()总是会返回一个离谱的值,直到我初始化数组:

char testArray [50] ='';

代替

炭testArray [50];

我使用Visual Studio 2015年

多亏了这些成绩!

+3

'char test [Max];'定义一个数组,但不是它的内容,在写入之前它仍然未初始化。读取未初始化的数据是未定义的行为。这意味着'strlen'今天可以返回61,明天5,崩溃或者做任何其他事情。要清楚的是,'strlen'返回找到字符''\ 0''前的字符数。 –

+0

你期望发生什么,为什么? –

+0

为什么你认为一个未初始化的数组不能包含离谱值? – Kevin

回答

3

我认为基本的误解是 - 不像在其他语言 - 在C,局部定义的变量不与任何值初始化,既不是空字符串,也不能与0,也不能与任何<undefined>或什么,除非你明确地初始化它们。

注意,在访问未初始化的变量实际上是“不确定的行为”;它可能导致“有趣的”和非确定性的结果,可能会崩溃,甚至可能被忽略。这种方案的

一个很常见的行为(虽然明确不保证!)是,如果你写

char test[50]; 
int length = strlen(test); 

然后test将指向一些内存,这是在50字节大小保留,又大大地任意字符,不一定是\0-字符。因此,test可能不会在这个意义上的第一个字符是一个\0因为这将是一个真正的空字符串""“空”。如果你现在通过调用strlen(test)访问test(这实际上是UB,因为说的),然后strlen可能只是通过这个任意填充的内存,它可能在第一50字符内检测\0,也可能检测到第一\0多后已超过50字节。

+1

好吧谢谢澄清每个人,我现在明白,简单地声明一些东西并不意味着它已初始化 - 并试图读取未初始化的变量将与c + +拧谢谢斯蒂芬和弗朗索瓦,俄罗斯人,和其他讽刺家伙。让我大笑! –

+0

:-)如此热情接受其中的一个答案,以便将主题标记为已解决。 –

0

这是很好的,你已经找到你的答案,但你要明白,这怎样事情的作品,我想。

char test[MAX]; 

在这行代码中,您刚刚声明了一个MAX字符数组。在你初始化它之前,你会得到这个数组中的随机值。 strlen函数遍历内存直到找到0值。所以,由于数组中的值是随机的,因此该函数的结果是随机的。此外,你可以轻松地走出阵列并获得UB。

char test[MAX] = ''; 

此代码initilizes与这样的strlen将能够找到它0值“测试”数组的第一个元素。

+0

它应该是'char test [MAX] =“”;',''''版本是一个语法错误 –

+0

这是真的,它只是一个错字 –