what should strlen() really return in this code?

痞子三分冷 提交于 2019-12-02 04:10:54

问题


#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;
}

Look at the code above. The array qq has four elements in it and the array qqq has five elements in it the last of which is '\0'. So I understand line A prints 4 and line C prints 5. Line D is OK with me. I understand that strlen(qqq) equals "sizeof qqq / sizeof qqq[0] - 1" when dealing with strings. But Line B prints 15 which makes me puzzled. Why? (I use vs2012.)


回答1:


In your code

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

qq is not qualified to be called a string, as it is not null-terminated. So calling strlen() wilh qq is inviting trouble.

What actually happens here is, strlen() goes past the last valid element in qq in search of terminating null (which is actually missing), and thus, venture into out-of-bound memory, which invokes undefined behaviour.

Solution: To make qq a string, you have to add the null-terminator in the initializer list yourself, like

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

That said, as I already mentioned in my comment, as strlen() return type is size_t, you should use %zu format specifier to print the result.


Just in a lighter mood, to answer

what should strlen() really return in this code?

If I say, "The phone number of the Respected President of India", well, technically, I might be correct !!

On a serious note, the output of UB in, well, undefined.




回答2:


Your string is not null-terminated. That means your code is not deterministic. strlen() will terminate whenever it encounters a \0 (null byte/character); the result can vary due to it sequential scanning until the \0 is encountered.




回答3:


strlen() computes length of string but char qq[] = {'a' , 'b' , 'c' , 'd'}; is not string. Undefined results are obtained when 'Non-String' data is passed to strlen.

Strings are null terminated in c.

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




回答4:


strlen will work its way forward until it finds a \0 character, counting how many characters there are along the way.

Because qq does not have a \0 in it, strlen will keep going into other, unrelated memory. Eventually, by chance, it encounters a \0 byte.

Apparently for you that is after 15 bytes (or 11 bytes beyond the end of qq).
But it is not deterministic or guaranteed, and is very unsafe.
It is very possible that strlen will end up trying to read invalid memory before it happens to find a \0 character, in which case your program will seg-fault.



来源:https://stackoverflow.com/questions/32052286/what-should-strlen-really-return-in-this-code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!