![]() |
|
#1
|
|||
|
|||
scanf and Check Failure #2 errorThis program is taking input and spitting it back out. It is only to accept a single character a-z. then print it back out and wait for me to enter any number so I can see what was printed then end the program. After entering a valid number and seeing the result I enter a number to end the program I get the following error:
Run-Time Check Failure #2 - Stack around the variable 'stateRank' was corrupted. I'm not sure why, can you guys clue me in on the answer? CPP / C++ / C Code:
|
|
#2
|
|||
|
|||
|
Quote:
The "%[" format specifier causes this to happen (quoting from the C standard): Quote:
So the argument must be the address of an array large enough to hold all of the input characters (between a and z) entered by the user, plus one to hold the terminating '\0'. In other words, if you enter one char, say, 'x', scanf stores this at the address of stateRank, then stores a '\0' in the next address. The next address does not belong to you. (In general, the only data addresses that belong to you are addresses of non-const declared variables, or locations within blocks of memory obtained from malloc() or its cousins.) Some compilers assign addresses for automatic variables on integer boundaries, some pack them in, some do other things. Any given compiler might not choke on this bug, but it is a bug. I tested the program on my Windows box (Borland, Microsoft, and GNU compilers) and my Linux box (GNU compiler). I couldn't make the program crash by entering a single character, but I got a crash every time by entering more than 13 'x' characters (or 13 anythings between a and z). The scanf function is not safe for reading strings with %s or with %[]. Remember, scanf only knows what you give it as arguments. It doesn't know if your pointer points to enough legal memory to handle all possible user input. You were lucky that you saw the error now. This is a hidden time bomb waiting to wreak havoc some day. This is precisely the kind of "buffer overflow" bug that is exploited by script kiddies and other malefactors. Typically it is not caught at compile time, and may or may not be discovered by testing, depending on the experience and skills of the tester(s). One possible fix for your particular requirements: declare stateRank to be an array of two chars, then use the following scanf: CPP / C++ / C Code:
Now, by putting a limit value of 1 in the format specifier, scanf will store an input char in stateRank[0], and will store '\0' in stateRank[1]. Scanf will always store the '\0', so two chars is the minimum size for stateRank. Regards, Dave Last edited by davekw7x : 17-Sep-2005 at 12:07.
|
|
#3
|
||||
|
||||
|
Or better yet, use getchar() instead of scanf() -- this post and its followup together explain why
__________________
Age is unimportant -- except in cheese |
Recent GIDBlog
Developing GUIs with wxPython (Part 2) by crystalattice
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Re: Things to Avoid in C/C++ -- gets() , Part 1 | WaltP | C Programming Language | 5 | 21-Jun-2007 12:13 |
| RSA program | fwongmc | C Programming Language | 11 | 08-Nov-2004 22:15 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The