-4

I tried the following code on GNU GCC compiler and its giving me output as 26. But I don't understand how the code is working especially what actually strlen() function is doing.

#include<iostream>
#include<stdio.h>
#include<string.h>

using namespace std;

int main()
{
    char b[]={'G','E','E','K','S',' ','F','O','R',' ','F','U','N'};
    cout<<sizeof(b)<<endl;
    cout<<strlen(b)<<endl;
    return 0;
}
  • 9
    You may not pass `b` to `strlen` if it's not null terminated. – François Andrieux Aug 27 '18 at 17:31
  • 1
    strlen is encountering some random null character after the string - this is undefined behaviour. –  Aug 27 '18 at 17:32
  • But its working except that for giving o/p 13, its giving output 26 – Shashank Shekhar Aug 27 '18 at 17:33
  • 2
    " its giving output 26 " - then it's not "working", is it? –  Aug 27 '18 at 17:33
  • 1
    It's not because compilation succeeds that your code works or is error-free. – François Andrieux Aug 27 '18 at 17:34
  • There can be a byte with the value 0 somewhere after the string within unallocated memory. The distance strlen will iterate after your array is implementation defined. It may also trigger a memory access error which is also implementation defined. – Chris Rollins Aug 27 '18 at 17:36
  • 1
    A statement can be Grammatically correct without making sense logically. [See the Jabberwocky](https://en.wikipedia.org/wiki/Jabberwocky). Getting code to compile is often only the start of the job. – user4581301 Aug 27 '18 at 17:41
  • 4
    I think your problem is your understanding of "working". Just because a program compiles and runs does not mean it is working. If the program exhibits undefined behavior (UB). Then the code can literally do anything (including appear to work). The trouble is that UB can change very easily from looking like it works to crashing to formatting your hard drive. You just make a minor alteration to the program and it can change (or simply recompile on a different OS or with a different compiler). What you have done here is break the pre-conditions required for `strlen()` and thus your code has UB. – Martin York Aug 27 '18 at 17:54

4 Answers4

6

What is the length of string when we don't explicitly initialize a character array with null character?

The length of the string is the number of characters it contains. (Let us ignore for simplicity the fact that there is a difference between the number of graphemes, code points and code units, all of which are the length of the string depending on perspective. In the context of this answer, character == code unit).

The length of a null terminated string is the number of characters before the null terminator. If a string doesn't contain a null terminator, then it isn't a null terminated string.

strlen(b)

b isn't a null terminated string. strlen requires that the argument points to a null terminated string. If the requirement isn't satisfied, the behaviour of the program is undefined.

But its working except that for giving o/p 13, its giving output 26

The behaviour is undefined. Possible behaviours include, none of which are guaranteed:

 - working
 - not working
 - random output
 - non-random output
 - the expected output
 - unexpected output
 - no output
 - any output
 - crashing at random
 - crashing always
 - not crashing
 - corruption of data
 - different behaviour, when executed on another system
 -                    , when compiled with another compiler
 -                    , on tuesday
 -                    , only when you're not looking
 - same behaviour in all of the above cases
 - anything else within the power of the computer (hopefully limited by the OS)

Undefined behaviour is undesirable in any program.

eerorika
  • 232,697
  • 12
  • 197
  • 326
4

But I don't understand how the code is working especially what actually strlen() function is doing.

When you pass a string to strlen that is not null terminated, you are invoking undefined behavior. Don't count on any predictable behavior.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • So does it mean that on random machine it will give some random output? – Shashank Shekhar Aug 27 '18 at 17:35
  • 1
    @ShashankShekhar The behavior may even change on the same machine for any reason at any time. See https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior – François Andrieux Aug 27 '18 at 17:36
  • @ShashankShekhar, that's one possibility. The trouble is that with UB, *anything can happen.* You can't count on any predictable behavior. – R Sahu Aug 27 '18 at 17:37
  • 3
    The deal with the C++ compiler is: if you (the programmer) follow the rules, then they (the C++ compiler implementers) promise to output a program that does what the rules say it will do. The flip side of that deal is that if you (the programmer) don't follow the rules, then they (the C++ compiler implementers) don't guarantee anything at all -- you'll get whatever behavior you get, and no sympathy from anyone ;) . – Jeremy Friesner Aug 27 '18 at 17:40
  • @Shashank Shekhar "So does it mean that on random machine it will give some random output?" - You don't get even that guarantee from the C++ standard. If a program contains Undefined Behavior *anywhere* then the compiler is free to do *whatever it wants* to *any* part of the program. The entire program is without meaning and no behaviour at all is guaranteed *anywhere* (no diagnostic required). – Jesper Juhl Aug 27 '18 at 17:54
  • On many platforms, the length of a C-style string that is not nul terminated is the length until it finds one. The `strlen` function will count characters until if finds a nul character, or the world ends. – Thomas Matthews Aug 27 '18 at 19:49
0

The Length of String or strlen refers to a C string that is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself). for example:

char TestStr[25] = "Test String";

if you use sizeof(TestStr) it will evaluate the 25 chars in the array but with strlen(TestStr) will evaluate only 11.

Hope this helps

Hasan Patel
  • 412
  • 7
  • 19
0

Another case related to your issue:

int main()
{
  static const char fun_text[] = {'f', 'u', 'n', '\0', 'c', 'a', 's', 'e'};
  std::cout << strlen(fun_text) << std::endl;
  std::cout << sizeof(fun_text) << std::endl;
  return 0;
}

In the above case, the array size is 8.
However, the strlen function will return 3 because it runs into a '\0' character before reaching the end of the array.

Summary

The strlen function returns length based on content.
The sizeof operator return the length of the array, regardless of content.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154