admin管理员组文章数量:1319472
#include <stdio.h>
#include <string.h>
void f(char s1[], const char s2[], int i, int j) {
if (i >= 0 && j >= 0) {
s1[i] = s2[j];
f(s1, s2, i + 1, j - 1);
}
}
int main() {
char s1[5] = {'\0'}, s2[] = "hello";
f(s1, s2, 0, (int)strlen(s2) - 1);
printf(" %s \n", s1);
return 0;
}
Hello, The print of this code is olleh but I expected the code to give an error as the null character was overwritten during the for loop, why this happen?
#include <stdio.h>
#include <string.h>
void f(char s1[], const char s2[], int i, int j) {
if (i >= 0 && j >= 0) {
s1[i] = s2[j];
f(s1, s2, i + 1, j - 1);
}
}
int main() {
char s1[5] = {'\0'}, s2[] = "hello";
f(s1, s2, 0, (int)strlen(s2) - 1);
printf(" %s \n", s1);
return 0;
}
Hello, The print of this code is olleh but I expected the code to give an error as the null character was overwritten during the for loop, why this happen?
Share Improve this question asked Jan 19 at 19:27 Tommaso AnsaloniTommaso Ansaloni 91 silver badge1 bronze badge 6 | Show 1 more comment2 Answers
Reset to default 4If you try to print using %s
and pass a non-null-terminated string, it will invoke undefined behavior.
However, in your case, char s1[5] = {'\0'}
fills the entire array with zeroes. Therefore, if strlen(s2) < sizeof(s1)
(s1
and s2
in the main
function scope), this code will work correctly.
If strlen(s2) >= sizeof(s1)
, it will invoke undefined behavior because:
- You will write outside the array bounds if
strlen(s2) > sizeof(s1)
. - You will pass a non-null-terminated string to
printf
ifstrlen(s2) >= sizeof(s1)
.
The print of this code is
olleh
, but I expected the code to give an error since the null character was overwritten during the for loop. Why does this happen?
Overwriting the first character does not matter because your array is zeroed out when initialized as you did. The issue arises because there is no space for a null-terminating character if the conditions I explained above are met. This invokes undefined behavior. Undefined behavior does not have to manifest in a specific way—the code might work fine, cause a segmentation fault, transfer all your money, or do something else entirely.
In your case, it is likely that there was a zero in the next byte past the end of the s1
array.
… I expected the code to give an error…
It is incorrect to expect this. When printf
is passed, for a %s
conversion, an array that does not contain a null character, then the behavior is not defined by the C standard.
Nothing specifies that the computer will give an error. There is no specification from the C standard about what the behavior will be.
Often, what will happen is that printf
will continue examining memory beyond the end of the array and printing what it finds until a zero byte is found. There might have been a zero byte immediately after your s1
array, so printf
stopped right away. However, other behaviors are possible. printf
might have printed additional characters that you did not see because they had no visible effect, like spaces or tabs or certain control characters. In other situations, there might be other characters beyond your array, and printf
might print those. Or, during optimization, the compiler might have transformed your program in ways that produce other effects.
本文标签: cUnexpected null character behaviour when inserting into an arrayStack Overflow
版权声明:本文标题:c - Unexpected null character behaviour when inserting into an array - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742061176a2418594.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
s1
start out as "the null character", and you overwrite all of them. What you need to remember is thats2
is an array of six characters, and you need to makes1
at least the same size. – Some programmer dude Commented Jan 19 at 19:35i >= 0
will always be true, as it starts out as0
and then only get increased in the recursive calls. – Some programmer dude Commented Jan 19 at 19:36f
is doing, and what the argument variablesi
andj
represent. Comments could also help. For example, I would probably namef
ascopy_reverse
or something similar, ands1
would bedest
,s2
would besource
, andi
andj
would then bedest_pos
andsource_pos
(respectively). – Some programmer dude Commented Jan 19 at 19:38s1
is{'o', 'l', 'l', 'e', 'h'}
(all 5 bytes of the array). It's an error (it's UB) to use that inprintf()
with"%s"
because no'\0'
is present; or, in other words, becauses1
is NOT a string. One of the possible manifestations of UB is behaving like expected (the most annoying UB and most difficult to diagnose and correct). – pmg Commented Jan 19 at 19:43