Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
367 views
in Technique[技术] by (71.8m points)

c - Null termination of char array

Consider following case:

#include<stdio.h>
int main()
{
    char A[5];
    scanf("%s",A);
    printf("%s",A);
}

My question is if char A[5] contains only two characters. Say "ab", then A[0]='a', A[1]='b' and A[2]=''. But if the input is say, "abcde" then where is '' in that case. Will A[5] contain ''? If yes, why? sizeof(A) will always return 5 as answer. Then when the array is full, is there an extra byte reserved for '' which sizeof() doesn't count?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you type more than four characters then the extra characters and the null terminator will be written outside the end of the array, overwriting memory not belonging to the array. This is a buffer overflow.

C does not prevent you from clobbering memory you don't own. This results in undefined behavior. Your program could do anything—it could crash, it could silently trash other variables and cause confusing behavior, it could be harmless, or anything else. Notice that there's no guarantee that your program will either work reliably or crash reliably. You can't even depend on it crashing immediately.

This is a great example of why scanf("%s") is dangerous and should never be used. It doesn't know about the size of your array which means there is no way to use it safely. Instead, avoid scanf and use something safer, like fgets():

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('') is stored after the last character in the buffer.

Example:

if (fgets(A, sizeof A, stdin) == NULL) {
    /* error reading input */
}

Annoyingly, fgets() will leave a trailing newline character (' ') at the end of the array. So you may also want code to remove it.

size_t length = strlen(A);
if (A[length - 1] == '
') {
    A[length - 1] = '';
}

Ugh. A simple (but broken) scanf("%s") has turned into a 7 line monstrosity. And that's the second lesson of the day: C is not good at I/O and string handling. It can be done, and it can be done safely, but C will kick and scream the whole time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...