The c programming book says that my string must be null terminated to print it using printf but still the following program prints the string despite it being non null terminated !!
#include <stdio.h>
#include <stdlib.h>
int main(){
int i ;
char str[10] ;
for(i = 0 ; i < 10 ; i++ ) {
str[i] = (char)(i+97) ;
}
printf("%s",str) ;
}
I am using codeblocks IDE .
It's undefined behavior to read beyond the bounds of an array, you were actually unlucky it didn't crash, if you run it enough times or call it in a function it may (or may not) crash, you should always terminate the string, or use a width specifier:
printf("%.10s", str);
Whatever is after the 10th element of str
happens to be a null. That null is outside the defined bounds of the array, but C doesn't have array bounds checking. It's just luck in your case that that's how it worked out.
According to C standard the printf function prints the character in the string until it finds a null character. Otherwise after the defined array index what it will do is not defined. I have tested your code. and after printing "abcdefghij it prints some garbage value.
If you do other things before that call, your stack area will contain other data than an unused one. Imagine that:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int use_stack(void) {
char str[500];
memset(str, 'X', sizeof(str));
printf("Filled memory from %p to %p.\n", &str, &str+sizeof str);
}
void print_stuff() {
int i;
char str[16]; // changed that so that 10..15 contain X
for(i = 0; i < 10; i++) {
str[i] = (char)(i+97);
}
printf("%s<END>",str); // have a line break before <END>? Then it comes from i.
printf("&str: %p\n", &str);
printf("&i: %p\n", &i);
// Here you see that i follows str as &i is &str + 16 (0x10 in hex)
}
int main() {
use_stack();
print_stuff();
}
your stack area will be full of X
es and printf()
will see them.
In your situation and your environment, the stack is coincidentically "clean" on program start.
EDIT: This may or may not happen. If the compiler puts the variable i
immediately after the array, your data will nevertheless be NUL
-terminated, because the first byte is the value of i
(which you happen to print as well -it might be a libne break in your case - and the 2nd byte is a NUL
byte. Even if this is the case, your code invokes UB (undefined behaviour).
Can you have a look (by piping the program output into hexdump
or alike) if your output contains a 0A
character? If so, my guess is correct. I just tested it, an on my compiler (gcc
) it seems to be the way.
As said, nothing you should rely on.
EDIT2: If you see a line break before <END>
, my guess was right. And if you have a look at the pointers now being printed, you can compare their addresses in memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With