Array of characters in C

When we define an array of characters as "char name [10]", this indicates that the array "name" may contain a string of ten characters in length. But in the program below, an array name can contain more than ten characters. How is this possible?

//print the name of a person. char name[10]; scanf("%s",name); printf("%s",name); 

Here, if I enter a name longer than ten characters, there is no runtime error, and the program prints all the characters I entered. If I enter a name of twenty or more characters, there is a program termination.

Note. I am running a program on Ubuntu9.04 using the gcc compiler.

+4
source share
9 answers

scanf allows you to specify a maximum width specifier, as in

 scanf("%9s", name); 

This will read up to 9 characters and add a trailing NUL character, for a total of 10 characters.

What happens if you do not limit the number of scanf characters that can read? Well, then your line ends with rewriting something else. In this case, I think your buffer is on the stack, so you are overwriting something on the stack. The stack contains local variables, returns addresses (to the function that calls this function) and the arguments of the function. Now, an attacker can fill this buffer with arbitrary code and rewrite the return address with the address of this code (there are many variants of this attack). An attacker can execute arbitrary code through this program.

+3
source

Since scanf does not know how long the array takes. The variable "name" does not refer to the type of "array", but refers to the type of "pointer" (or "address"). He says, start writing here and keep writing until you are done. You might be lucky and you have something else non-critical in your stack that will be overwritten, but ultimately scanf will write and write and overwrite something fatal and you will get a segmentation error. That is why you should always pass the size of arrays.

It is like giving a blind person a pencil and saying, β€œStart writing here,” without being able to see where the paper ends. In the end they will write on the table and damage something. (Note: this is not a blind knock, it is just a metaphor.)

In the above case, I highly recommend using fgets () to grab a certain amount from stdin and then sscanf () to pull any information from this line and put it in separate variables as needed. Scanf () and fscanf () are evil, I have never found for them that fgets () + sscanf () cannot solve it more safely.

 char line[1024]; /* arbitrary size */ if( fgets( line, 1024, stdin ) != NULL ) { fprintf( stdout, "Got line: %s", line ); } 

Or for things behind the lines:

 # cat foo.c #include <stdio.h> int main( int argc, char **argv ) { int i; char line[1024]; while( fgets( line, 1024, stdin ) != NULL ) { if( sscanf( line, "%d", &i ) == 1 ) { /* 1 is the number of variables filled successfully */ fprintf( stdout, "you typed a number: %d\n", i ); } } } # gcc foo.c -o foo # ./foo bar 2 you typed a number: 2 33 you typed a number: 33 <CTRL-D> 
+6
source

With an array of 10 characters to represent a string in C. In fact, you can only use 9 characters and a zero-terminated character. If you use more than 9 characters (+1 termination), then you will have undefined behavior.

You just rewrite the memory, which should not be. What will happen, whether segfault will work or as you expect, is as good as random.

+4
source

Welcome to the world of C ...

  • C does not check the bounds of the array;
  • the name of the array is nothing more than a pointer to the first element of the array;
  • scanf (used by Mohit program) does not handle destination buffer size limits;
  • with the wrong pointer value that you can write anywhere in memory, and you should expect unpredictable behavior, segmentation errors, if you're lucky.
+2
source

C does not have array length checks. This will allow you to overflow the array.

In this case, a record may be written after the array, so you won’t work if you overwhelm a small amount (although who knows that you are corrupting).

Try this code and see what happens if you enter more than 10 characters.

 char name[10]; char name2[10]; scanf("%s",name); printf("%s",name); printf("%s",name2); 

Also, the array of names can contain 9 characters, the 10th should be the final zero zero of '\ 0'

+1
source

How is this possible?

An array is allocated on the stack. After that, there may be empty space or data that is less important than the national security value (for example, callee-saves registers that are not actually used in the caller). After all, if the name you enter is long enough, you are rewriting something important. Including, with some compilers, the return address!

Running a program under valgrind will instantly detect an overflow error.

+1
source

Your code causes Undefined Behavior. Never use scanf() to read a string, use fgets() .

scanf() and gets() have the same memory overflow problem. You can easily read more characters than char[] can hold.

0
source

You use undefined behavior, so anything can happen - the program may work or work normally or start doing something strange.

0
source

When you say char c [10], you allocate 10 bytes for this variable. However, your program may also have subsequent bytes, so you cannot get segfault. But you will encounter many other problems that you wish segfault received.

0
source

Source: https://habr.com/ru/post/1315341/


All Articles