2

I am trying to understand the array concept in string.

char a[5]="hello";

Here, array a is an character array of size 5. "hello" occupies the array index from 0 to 4. Since, we have declared the array size as 5, there is no space to store the null character at the end of the string.

So my understanding is when we try to print a, it should print until a null character is encountered. Otherwise it may also run into segmentation fault.

But, when I ran it in my system it always prints "hello" and terminates.

So can anyone clarify whether my understanding is correct. Or does it depends upon the system that we execute.

6
  • 3
    Undefined behaviour. Commented May 8, 2018 at 18:46
  • 1
    That's one of the big problems with undefined behavior: it can be completely invisible (usually until you change something completely unrelated somewhere else and it starts to bite). Commented May 8, 2018 at 18:47
  • 1
    I upvoted this question. Research effort is shown and the doubt is clearly expressed. There are countless similar questions (most of lower quality). I guess we're missing a FAQ entry in the C tag wiki along the lines of "I did something in C that should be wrong, but it seems to work" ;) Commented May 8, 2018 at 19:03
  • "when we try to print a" lacks posting the code used to do that. puts(a) is UB, yet printf("%.5s\n", a); is OK. Commented May 8, 2018 at 19:08
  • "when I ran it" --> there is no code that shows what was run. It is easy to make a good guess what OP is doing, yet still a guess. A better post would include a minimal reproducible example. Commented May 8, 2018 at 19:09

2 Answers 2

4

As ever so often, the answer is:

Undefined behavior is undefined.

What this means is, trying to feed this character array to a function handling strings is wrong. It's wrong because it isn't a string. A string in C is a sequence of characters that ends with a \0 character.

The C standard will tell you that this is undefined behavior. So, anything can happen. In C, you don't have runtime checks, the code just executes. If the code has undefined behavior, you have to be prepared for any effect. This includes working like you expected, just by accident.

It's very well possible that the byte following in memory after your array happens to be a \0 byte. In this case, it will look to any function processing this "string" as if you passed it a valid string. A crash is just waiting to happen on some seemingly unrelated change to the code.

You could try to add some char foo = 42; before or after the array definition, it's quite likely that you will see that in the output. But of course, there's no guarantee, because, again, undefined behavior is undefined :)

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

Comments

1

What you have done is undefined behavior. Apparently whatever compiler you used happened to initialize memory after your array to 0.

Here, array a is an character array of size 5. "hello" occupies the array index from 0 to 4. Since, we have declared the array size as 5, there is no space to store the null character at the end of the string.

So my understanding is when we try to print a, it should print until a null character is encountered.

Yes, when you use printf("%s", a), it prints characters until it hits a '\0' character (or segfaults or something else bad happens - undefined behavior). I can demonstrate that with a simple program:

#include <stdio.h>

int main()
{
    char a[5] = "hello";
    char b[5] = "world";
    int c = 5;
    printf("%s%s%d\n", a, b, c);
    return 0;
}

Output:

$ ./a.out 
helloworldworld5

You can see the printf function continuing to read characters after it has already read all the characters in array a. I don't know when it will stop reading characters, however.

I've slightly modified my program to demonstrate how this undefined behavior can create bad problems.

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

int main()
{
    char a[5] = "hello";
    char b[5] = "world";
    int c = 5;
    printf("%s%s%d\n", a, b, c);

    char d[5];
    strcpy(d, a);
    printf("%s", d);
    return 0;
}

Here's the result:

$ ./a.out 
helloworld��world��5
*** stack smashing detected ***: <unknown> terminated
helloworldhell�p��UAborted (core dumped)

This is a classic case of stack overflow (pun intended) due to undefined behavior.

Edit:

I need to emphasize: this is UNDEFINED BEHAVIOR. What happened in this example may or may not happen to you, depending on your compiler, architecture, libraries, etc. You can make guesses to what will happen based on your understanding of different implementations of various libraries and compilers on different platforms, but you can NEVER say for certain what will happen. My example was on Ubuntu 17.10 with gcc version 7. My guess is that something very different could happen if I tried this on an embedded platform with a different compiler, but I cannot say for certain. In fact, something different could happen if I had this example inside of a larger program on the same machine.

5 Comments

Upvote for a practical example, but please add that "YMMV" -- it's undefined, after all.
@FelixPalmen What is "YMMV"?
"your mileage may vary" -- just because it's undefined :) (and therefore depends on the compiler, standard lib, operating system, processor architecture, etc. pp.)
@FelixPalmen Ah, thanks. I'm not well-versed in all the internet slang.
de rien. I think your edit is good (thanks) and makes this a very valuable answer, but I can't upvote twice ;) (now, only the nasal demons are missing ... hehehe, joking)

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.