1

Given a string , say ,

char *str = "Hello,StackOverflow!"
char newStr[30];
int l = strlen(str);
for(int i =0 ; i<l ; i ++ )
   newStr[i] = str[i];
printf("%s" , newStr);

Now , we know that the last character of a c-string has to be '\0' , Since here we haven't explicitly done the same ( store '\0' at last index of string newStr) , this program should crash since printf won't find the end of string.

But I noticed that it was working fine sometimes and sometimes it wasn't. What could be the problem ? It was working almost everytime actually. Isn't it supposed to crash or give some run-time error?

Will it be the same case in C++ too ?

4
  • What is your definition of "crash"? What do you expect to happen? Commented Sep 17, 2012 at 16:17
  • @KerrekSB Sorry , that was supposed to be newStr. Commented Sep 17, 2012 at 16:20
  • The "anything might happen" answers are a bit sensationalist. You could speculate that the printf routine will continue to print until it hits an unrelated zero byte, which is often soon enough. Strictly speaking, it will likely be accessing memory outside the program's designated memory block, but blocks are fairly coarsely allocated, so you might not get an access violation most of the time. Commented Sep 17, 2012 at 16:42
  • 1
    @sTEAK., to address your other comments about how to alter you code, look at strcpy, or its brother strncpy, cplusplus.com/reference/clibrary/cstring/strcpy Commented Sep 17, 2012 at 18:46

6 Answers 6

7

No. It invokes undefined behavior - it means it doesn't have to crash - it can do literally anything, like nasal demons.

Also, "gives a runtime error" - well, that depends on what do you mean by a runtime error. There's no dynamic runtime for C - if you expect a nicely formatted error message from an exception, that wouldn't happen. What would happen is most likely a segmentation fault.

All in all, if one causes/uses undefined behavior, he must not rely on it crashing or not crashing.

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

5 Comments

@JoshPetitt unexpected, abnormal termination of a program due to it having semantic errors.
does '\0' get added explicitly or not at the end of string newStr ?
@sTEAK. no, it doesn't - as you correctly expect, strlen() returns the string length without the terminating 0, so it doesn't get copied over.
@H2CO3, that is a reasonable definition that I think lies at the heart of the OP's question. The OP should think about what a "crash" is and what could cause a "crash". Like you've said, the access violation is probably the most likely to occur, but this is a secondary effect of undefined behavior, not the direct effect of the code being executed. +1 for nasal demons :-)
@JoshPetitt right. I just thought I quite understood what OP meant about what a crash is :)
3

A "crash" is not guaranteed. A program that improperly handles null terminators in strings - more generally accesses data outside of buffer boundaries - or violates the printf format string, may seem to work just fine, functioning and not e.g. causing a segfault. But this is just happenstance: the behavior of your code is undefined.

It will be the same in C++.

2 Comments

does '\0' get added explicitly or not at the end of string newStr ?
it does not get added explicitly. The memory at the address beyond the last character may happen to contain the null character.
2

I would suspect that most of the time it would keep printing past the "!" and keep going in memory until it hits a NULL. Which could result in a crash, but doesn't have to.

This is why it's best to either:

memset(newStr, 0, 30);

or

// This works because string literals guarantee a '\0' is present
// but the strlen returns everything up until the '\0'
int l = strlen(str) + 1;

this works too, but I don't feel it's as clear as adding one to strlen:

for(i =0 ; i<=l ; i ++ )

As the defination of strlen implies you need to.

3 Comments

If i do i<=l would that do ?
Yeah, that would work too... but IMO it's a little less clear why you're doing that.
@sTEAK. Yes, then it would copy the '\0' also.
1

By chance, most of the time the uninitialized bytes in newStr happen to be 0 in your particular case.

2 Comments

does '\0' get added explicitly or not at the end of string newStr ?
No, it doesn't, in your code. You should explicitly copy one extra character, or insert the 0 yourself, to make it safe.
1

Your program has undefined behaviour, since you promise to call printf with a pointer to a null-terminated string but fail to do so. Anything could happen, but your program is simply not correct.

Specifically, while reading the array elements one by one to find the null terminator, the program will eventually access an uninitialized variable, which is UB.

2 Comments

does '\0' get added explicitly or not at the end of string newStr ?
@sTEAK.: No, because strlen does not include the terminator. (The terminator is not part of the string, but only of the implementation.) So you need to say strlen(str) + 1, or use strncpy.
0

The behaviour of reading bytes that have not been initialized as characters is undefined in most implementations of C. Sometimes printf may write garbage, sometimes the program may find a null byte \0 after the last character and terminate normally. In some rare cases it may cause a crash. This is why you are seeing variation in what happens when you run the program. It depends on the compiler you are using, and what was in the memory location following that which you are allocating for the array.

(That is, if your program would compile - you've left off a semicolon)

2 Comments

does '\0' get added explicitly or not at the end of string newStr ?
@sTEAK. You need to add '\0' explicitly. The for loop you wrote only copies the non-null characters within strlen(str).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.