-2

Can anyone explain why this code:

char    t1[20];
char    t2[20];

memset(t1, 'B', sizeof(t1));
memset(t2, 'B', sizeof(t2));
printf("%lu\n", strlen(t1));
printf("%lu\n", strlen(t2));

result in:

22
21

Thank's

HB7
  • 5
  • 3
  • 3
    Note that both the lengths you get are longer than the actual arrays... you don't have a null char in the arrays to mark the end of the string, so `strlen()` keeps going 'til it finds one (past the end of the array somewhere). – Dmitri May 14 '16 at 20:17
  • 2
    Because you haven't null terminated either string, so you get garbage results. – Michael Burr May 14 '16 at 20:17
  • cannot reproduce the problem. – user3078414 May 14 '16 at 20:20
  • 1
    `strlen()` returns a result of type `size_t`. Use `"%zu"`, not `"%lu"`, to print it. (If your implementation doesn't support `"%zu"`, you'll need to cast the value to an appropriate type.) – Keith Thompson May 14 '16 at 20:26
  • 1
    You forgot to null-terminate your strings, so `strlen` is running past the end resulting in undefined behavior. Fix your bugs, *then* ask questions if you still don't understand. – Tom Karzes May 14 '16 at 22:06
  • You can initialise a `char`-array to all zeros by doing `char a[42] = "";`. – alk May 15 '16 at 07:59

1 Answers1

1

strlen expects to be given a (pointer to a) C string. A C string is an array of char terminated with the null character, '\0'.

When you memset your char arrays, you just write a 'B' into every element, thus neither of these arrays is a C string. Passing them to strlen is undefined behavior.

In order to fix this, set the last element of each array accordingly:

t1[19] = '\0';
t2[19] = '\0';
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
  • Interesting enough, different compilers seem to implement `memset` differently. llvm clang seems to put trailing `\0', whereas gcc doesn't. In any case you save yourself a lot of trouble if you 'null terminate' the C strings programmatically. – user3078414 May 14 '16 at 20:38
  • 1
    @user3078414 That's a false assumption: clang certainly does **not** put a trailing `'\0'`. What you're most likely witnessing is a combination of zero'd stack space and some sort of alignment (64 bit machine?), so that there is actually a null byte **after** the end of the arrays. – Daniel Jour May 14 '16 at 23:21
  • To be accurate, this "*`strlen` expects to be given a (pointer to a) *C string*.*" should read "*`strlen` expects to be given a (pointer to the first element of a) *C string*.*" – alk May 15 '16 at 08:01
  • @Daniel Jour. I didn't mean to challenge your expert knowledge. Yet a heretic question is here: how come there is a `null byte`-effect in the end of the arrays created using `clang`, whereas none using `gcc` **on the same machine**, same OS? I could consistently reproduce the problem. – user3078414 May 15 '16 at 10:12