0

I have to implement a function that determines the length of a string without using library functions. My function looks like this:

int getLength(char strg[]) {
    int length = 0;

    while(strg[length] != '\0') {
        length++;
    }

    return length;
}

With the inputs

char test1[7] = "BlaBlaB"

as well as

char test2[8] = {'B','l','a','B','l','a','B','l'}

the function returns the values 11 and 12, which are of course wrong.

However, with

char test1[8] = "BlaBlaB"

or

char test2[9] = {'B','l','a','B','l','a','B','l'}

the function returns the correct results.

So to sum it up, only for the cases where the array is assigned as many elements as it is defined to be allowed to hold, and only when the number of elements is 7 or 8, this bug occurs. Also, it doesn't matter if I assign the value with String notation ("ab...") or if I assign it in array notation ({'a','b','.','.','.'}).

Does anyone have an explanation for this weird behaviour?

Michele Dorigatti
  • 811
  • 1
  • 9
  • 17
  • 1
    `char test1[7] = "BlaBlaB"` there is no `'\0'` character. In `char test2[8] = {'B','l','a','B','l','a','B','l'}` there is no `'\0` character either. – KamilCuk Dec 04 '19 at 12:52
  • For your `test2` array you explicitly fill all elements, but you don't set any of them to the null-terminator `'\0'`. Now think about how your comparison `strg[length] != '\0'` would work if there isn't a `'\0'` in the array? – Some programmer dude Dec 04 '19 at 12:55
  • @KamilCuk okay, but why does this work with `test3[9] = "BlaBlaBla"` and `test4[6] = "BlaBla"` then? – InterFelix Dec 04 '19 at 13:04
  • Anything can happen. You are reading outside of allowed memory, outside of an array, your program behavior is undefined. It may work. It may not work. [Undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) – KamilCuk Dec 04 '19 at 13:06
  • This is not a "weird bug", as neither `char test1[7] = "BlaBlaB"` nor `char test2[8] = {'B','l','a','B','l','a','B','l'}` will have a `'\0'` terminator because you defined them so that they don't. – Andrew Henle Dec 04 '19 at 13:06

1 Answers1

2

getLength is fine although I'd use a size_t type for the length if I were you.

char test1[7] = "BlaBlaB" doesn't provide room for the NUL terminator, you need char test1[8] or, better still, leave the number out and let the compiler work it out for you. The same can be said for test2, although in that case there's no implicit NUL terminator in the r-value so you'd need to add that in yourself if you become wedded to that extremely tedious syntax for a char[] type declaration.

test3 is fine as you've provided ample room for NUL.

The behavior on running past the end of the arrays test1 and test2 is undefined. That explains the weirdness. Sometimes the program behaviour could be consistent with your expectations. On other occasions though the compiler might eat your cat.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Yes, I would also rather use non-fixed arrays, but one of the test-cases I need to solve is `char test2[7] = "BlaBlaB"` or something similar, the actual string doesn't matter here. How can I implement proper treatment of this test case? How would I go about detecting the end of this array to be able to return it's correct size? – InterFelix Dec 04 '19 at 13:03
  • @InterFelix In C the only way to get the length of `test1` (or `test2` as you write in your comment) is to use the `sizeof` operator. But this get the size of the *whole* array, not the length of a null-terminated string (and it won't work on pointers). If you need to use a function to get the lengths of the strings you can't use arrays that doesn't contain the terminator. If you're required by your teacher to handle that specific case, then you have to tell him or her that it's impossible. – Some programmer dude Dec 04 '19 at 13:05
  • @Someprogrammerdude but I still don't understand why it does work with the cases `test3[6] = "BlaBla"`, `test4[9] = "BlaBlaBla"` and everything below and above... – InterFelix Dec 04 '19 at 13:09
  • @InterFelix *but I still don't understand why it does work with the cases `test3[6] = "BlaBla"`, `test4[9] = "BlaBlaBla"`* It **doesn't** "work". It just doesn't produce an observable error. This time. – Andrew Henle Dec 04 '19 at 13:10
  • @InterFelix That's because going out of bounds of an array leads to *undefined behavior*. Sometimes it might seem to work (you're *lucky* that there just happens to be a terminator byte in the right position in memory), sometimes you get unexpected results, and sometimes you could summon [nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html). – Some programmer dude Dec 04 '19 at 13:17