2

I don't understand why strlen() is giving wrong value (ie: 9) only for the first string. After that the values are coming correctly.

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

int main() {
    int m, i, j;
    i = 2;
    j = 5;
    char a[i][j];
    for (i = 0; i <= 2; i++)  {
        scanf("%s", a[i]);
    }
    m = strlen(a[0]);
    printf("%d\n", m); //here the problem is coming//
    m = strlen(a[1]);
    printf("%d\n", m);
    m = strlen(a[2]);
    printf("%d\n", m);

    return 0;
}

INPUT:

heyman
jack
bro

OUTPUT:

9
4
3
9
  • 2
    You can only have strings up to 4 characters because j == 5. Commented Jul 21, 2020 at 8:44
  • 2
    heyman is writing out of bounds. Commented Jul 21, 2020 at 8:44
  • 1
    @fly_high j=5 will give you 5 characters to write, from 0 to 4, but strings need to have an additional character \0 at the end otherwise C doesn't know that the string is actually over. That means that from your maximum length you have to subtract 1 to account for this terminator \0 Commented Jul 21, 2020 at 8:53
  • 1
    @fly_high a[5] means you have positions a[0], a[1], a[2], a[3], a[4] available, i.e. 5 spaces not that the array will go up to a[5] Commented Jul 21, 2020 at 8:57
  • 2
    Rows and columns are the same. An array a[2] has only 2 elements with index 0..1. Commented Jul 21, 2020 at 9:14

2 Answers 2

10

Each row of a is only 5 bytes. When you read heyman into a[0], it overflows into a[1]. So you have:

a[0] = "heyma"
a[1] = "n\0"

Then when you read into a[1], you have

a[0] = "heyma"
a[1] = "jack\0"

Notice that there's no null terminator in a[0]. So when you call strlen(a[0]), it goes past the end of a[0] and continues searching in a[1] for the null byte. There are 5 bytes in a[0] and 4 bytes in a[1], so the length is 9. Technically, this is undefined behavior, but this is what happens in actual implementations because 2-dimensional arrays are contiguous.

In addition, when you read into a[2] you're completely outside the a array, resulting in undefined behavior.

Sign up to request clarification or add additional context in comments.

5 Comments

I wonder if overflowing from a[0] into a[1] is ub (obviously doing anything with a[2] is).
@PaulHankin I think I've read conflicting answers about it.
wow that was really interesting and i got all of the idea....thanks @Barmar
Appendix J.2 in the standard explicitly lists this kind of out of bounds multi-dimensional array access as an example of undefined behaviour: An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5])
It is UB when it overflows into a[1]
7

Since your array has length [2][5] you can store a maximum of 2 words of length 4, every word also has the terminating character \0 in addition to its letters.

You having as input heyman means you are writing too many letters and don't have enough space to also store the \0. Either try with a shorter word or change your length from 5 to 7.

Also you are storing 3 words in your array of length 2, the length refers to the number of elements stored not to the number you can go up to. Length 2 will have available positions 0 and 1 so when you are passing as input the third word you are trying to write outside of the array bounds.

2 Comments

He needs to change the length to at least 7: heyman has 6 characters plus null
@Barmar oh yeah you're right, for some reason i counted 5 characters in heyman instead of 6

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.