12 C-language questions involving pointers, processes, operations, structures, functions, memory, see how many you can make!
1.gets () function
Q: Please find the problem in the following code:
#include <stdio.h> int main (void) { char buff[10]; memset (buff,0,sizeof (Buff)); Gets (buff); printf ("\ n the buffer entered is [%s]\n", buff); return 0; }
A: The problem with the above code is the use of the function get (), which receives a string from stdin without checking the volume of the cache it replicates, which could cause the cache to overflow. It is recommended to use the standard function fgets () instead.
2.strcpy () function
Q: Below is a simple password protection feature, can you hack it without knowing the password?
#include <stdio.h> int main (int argc, char *argv[]) { int flag = 0; Char passwd[10]; memset (passwd,0,sizeof (passwd)); strcpy (passwd, argv[1]); if (0 = = strcmp ("Linuxgeek", passwd)) { flag = 1; } if (flag) { printf ("\ n Password cracked \ n"); } else { printf ("\ n incorrect passwd \ n"); } return 0; }
A: The key to cracking the above encryption is to exploit the vulnerability of the strcpy () function. So the user does not check the "passwd" capacity sufficiently when entering a random password to the "passwd" cache. Therefore, if the user enters a long "password" that is sufficient to cause the cache to overflow and overwrite the memory where the default value of the "flag" variable exists, even if the password cannot be verified, the flag verification bit becomes nonzero and the protected data can be obtained. For example:
$./psswd aaaaaaaaaaaaa Password cracked
Although the above password is not correct, we can still bypass the password security through the cache overflow.
To avoid such problems, it is recommended to use the strncpy () function.
Author Note: The most recent compiler detects the possibility of stack overflow internally, so it is difficult to store variables in the stack overflow. This is the default in my gcc, so I have to use the compile command '-fno-stack-protector ' to implement the above scenario.
return type of 3.main ()
Q: Can the following code be compiled and passed? If so, does it have any potential problems?
#include <stdio.h> void main (void) { char *ptr = (char*) malloc (n); if (NULL = = ptr) { printf ("\ n Malloc failed \ n"); return; } else { //do some processing free (PTR); } Return }
A: Because of the return type of the main () method, the error in this code is treated as a warning in most compilers. The return type of main () should be "int" instead of "void". Because the "int" return type causes the program to return a status value. This is important, especially when the program is running as part of a script that relies on the program to run successfully.
4. Memory leaks
Q: Does the following code cause a memory leak?
#include <stdio.h> void main (void) { char *ptr = (char*) malloc (n); if (NULL = = ptr) { printf ("\ n Malloc failed \ n"); return; } else { //Do some processing } return;}
A: Although the above code does not release memory allocated to "PTR", it does not cause a memory leak after the program exits. At the end of the program, all memory allocated by this program is automatically processed. But if the above code is in a "while loop," that would cause a serious memory leak!
Tip: If you want to know more about memory leaks and memory leak detection tools, you can take a look at our articles on Valgrind.
5.free () function
Q: The following program will have problems when the user enters ' freeze ', and ' zebra ' won't, why?
#include <stdio.h> int main (int argc, char *argv[]) {char *ptr = (char*) malloc (10); if (NULL = = ptr) {printf ("\ n Malloc failed \ n"); return-1; } else if (argc = = 1) {printf ("\ n Usage \ n"); } else {memset (PTR, 0, 10); strncpy (PTR, argv[1], 9); while (*ptr! = ' Z ') {if (*ptr = = ") break; else ptr++; } if (*ptr = = ' Z ') {printf ("\ n String contains ' z ' \ n '); Do some + processing} free (PTR); } return 0; }
A: The problem here is that the code (by adding "ptr") modifies the address of the "PTR" store in the while loop. When "Zebra" is entered, the while loop is terminated before execution, so the variable passed to free () is the address passed to malloc (). However, when "freeze", the address of the "PTR" store is modified in the while loop, resulting in an error in the address passed to free (), resulting in a seg-fault or crash.
6. Use _exit to exit
Q: In the following code, ATEXIT () is not called, why?
#include <stdio.h> void func (void) { printf ("\ n Cleanup function called \ n"); Return } int main (void) { int i = 0; Atexit (func); for (; i<0xffffff;i++); _exit (0); }
This is because the _exit () function is used, and the function does not call atexit () to clean up functions. If you use Atexit (), you should use Exit () or "return" to match it.
7.void* and C structural bodies
Q: Can you design a function that can accept any type of argument and return the Interger (integer) result?
A: The following:
int func (void *ptr)
If the function has more than one parameter, the function should be called by a struct, which can be filled with parameters that need to be passed.
8.* and + + operations
Q: What does the following operation output? Why?
#include <stdio.h> int main (void) { char *ptr = "Linux"; printf ("\ n [%c] \ n", *ptr++); printf ("\ n [%c] \ n", *ptr); return 0; }
Answer: The output should look like this:
[L] I
Because "+ +" and "*" have the same priority, "*ptr++" is equivalent to "* (ptr++)". That is, the ptr++ should be executed first, then the *ptr, so the operation result is "L". The second result is "I".
9. Q: Modify code Snippets (or read-only code)
Q: The following code snippet is wrong, can you point it out?
#include <stdio.h> int main (void) { char *ptr = "Linux"; *ptr = ' T '; printf ("\ n [%s] \ n", ptr); return 0; }
A: This is because, by *ptr = ' T ', the first letter of "Linux" will be changed in the in-memory code snippet (read-only code). This operation is not valid and therefore causes seg-fault or crashes.
10. Process that will change its name
Q: Can you write a program that changes the name of your process at run time?
Answer: see this code:
#include <stdio.h> int main (int argc, char *argv[]) { int i = 0; Char buff[100]; memset (buff,0,sizeof (Buff)); strncpy (Buff, argv[0], sizeof (buff)); memset (Argv[0],0,strlen (Buff)); strncpy (Argv[0], "NewName", 7); Simulate a wait. Check the process //name at this point. for (; i<0xffffffff;i++); return 0; }
11. Return the address of the local variable
Q: Is there a problem with the following code? If so, how do I change it?
#include <stdio.h> int* Inc (int val) { int a = val; a++; Return &a; } int main (void) { int a = ten; int *val = Inc (a); printf ("\ n incremented value is equal to [%d] \ n", *val); return 0; }
A: Although the above program can sometimes work correctly, there are serious vulnerabilities in "Inc". This function returns the address of the local variable. Because the life cycle of the local variable is the life cycle of the "Inc ()", the use of local variables at the end of the Inc will result in bad results. This can be avoided by changing the address of the variable "a" in main () so that the value stored in this address can be modified later.
12. Handling parameters for printf ()
Q: What does the following code output?
#include <stdio.h> int main (void) { int a = ten, B = +, c = +; printf ("\ n%d.. %d.. %d \ n ", a+b+c, (b = b*2), (c = c*2)); return 0; }
Answer: The output is:
110..40..60
This is because the parameters of the function in the C language are processed from right to left, and the output is from left to right.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
12 Interesting C-language questions and Answers