In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
C language programming in the five common mistakes and corresponding solutions, many beginners are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can get something.
Foreword:
The C language sometimes has a bad reputation because it is not as memory-secure as recent programming languages such as Rust. But with extra code, some of the most common and serious C language errors can be avoided.
Even the best programmers can't avoid mistakes completely. These errors can introduce security vulnerabilities, cause the program to crash, or cause unexpected actions, depending on the running logic of the program.
The following explains five errors that may affect your application and how to avoid them:
1. Uninitialized variable
When the program starts, the system allocates a piece of memory for storing data. This means that when the program starts, the variable gets a random value in memory.
Some programming environments deliberately "zero" memory when the program starts, so that each variable has an initial zero value. All the variables in the program take zero as the initial value, which sounds good. However, in the C programming specification, the system does not initialize variables.
Take a look at this sample program that uses several variables and two arrays:
# include # include int main () {int I, j, k; int numbers [5]; int * array; puts ("These variables are not initialized:"); printf ("I =% d\ n", I); printf ("j =% d\ n", j); printf ("k =% d\ n", k); puts ("This array is not initialized:"); for (I = 0; I < 5) Numbers +) {printf ("numbers [% d] =% d\ n", I, numbers [I]);} puts ("malloc an array..."); array = malloc (sizeof (int) * 5); if (array) {puts ("This malloc'ed array is not initialized:"); for (I = 0; I < 5; iTunes +) {printf ("array [% d] =% d\ n", I, array [I]) } free (array);} / * done * / puts ("Ok"); return 0;}
This program does not initialize the variable, so the variable takes a random value in the system memory as the initial value. When I compile and run this program on my Linux system, I see that some variables happen to have "zero" values, but others do not:
These variables are not initialized: I = 0j = 0k = 32766 This array is not initialized: numbers [0] = 0 numbers [1] = 0 numbers [2] = 4199024 numbers [3] = 0 numbers [4] = 0 malloc an array. This malloc'ed array is not initialized: array [0] = 0 array [1] = 0 array [2] = 0 array [3] = 0 array [4] = 0 Ok
Fortunately, the I and j variables start at zero, but the starting value of k is 32766. In the numbers array, most elements also happen to start at zero, and only the third element has an initial value of 4199024.
Compiling the same program on different systems can further show the dangers of uninitialized variables. Don't mistakenly think that "the whole world is running Linux", your program is likely to run on other platforms one day. For example, here is the result of running the same program on FreeDOS:
These variables are not initialized: I = 0j = 1074 k = 3120 This array is not initialized: numbers [0] = 3106 numbers [1] = 1224 numbers [2] = 784 numbers [3] = 2926 numbers [4] = 1224 malloc an array. This malloc'ed array is not initialized: array [0] = 3136 array [1] = 3136 array [2] = 14499 array [3] =-5886 array [4] = 219 Ok
Always remember the variables that initialize the program. If you want the variable to take zero as the initial value, add additional code to assign zero to the variable. Compiling this extra code in advance will help reduce the headache of debugging later on.
two。 Array out of bounds
In the C language, array indexes start from scratch. This means that for an array of length 10, the index is from 0 to 9; for an array of length 1000, the index is from 0 to 999.
Programmers sometimes forget this, and they reference the array from index 1, resulting in a "size difference" off by one error. In an array of length 5, the value that the programmer uses at index "5" is not actually the fifth element of the array. Instead, it is some other value in memory that has nothing to do with this array.
This is an array out of bounds of the sample program. The program uses an array of only five elements, but references array elements outside the range:
# include # include int main () {int i; int numbers [5]; int * array; / * test 1 * / puts ("This array has five elements (0 to 4)"); / * initalize the array * / for (I = 0; I < 5; iTunes +) {numbers [I] = I;} / * oops, this goes beyond the array bounds: * / for (I = 0; I < 10) Printf ("numbers [% d] =% d\ n", I, numbers [I]);} / * test 2 * / puts ("malloc an array..."); array = malloc (sizeof (int) * 5); if (array) {puts ("This malloc'ed array also has five elements (0 to 4)"); / * initalize the array * / for (I = 0; I < 5) Oops +) {array [I] = I;} / * oops, this goes beyond the array bounds: * / for (I = 0; I < 10; iBo +) {printf ("array [% d] =% d\ n", I, array [I]);} free (array);} / * done * / puts ("Ok"); return 0;}
As you can see, the program initializes all the values of the array (from index 0 to 4) and then reads from index 0, ending with index 9 instead of index 4. The first five values are correct, and the following values will confuse you:
This array has five elements (0 to 4) numbers [0] = 0 numbers [1] = 1 numbers [2] = 2 numbers [3] = 3 numbers [4] = 4 numbers [5] = 0 numbers [6] = 4198512 numbers [7] = 0 numbers [8] = 1326609712 numbers [9] = 32764 malloc an array. This malloc'ed array also has five elements (0 to 4) array [0] = 0 array [1] = 1 array [2] = 2 array [3] = 3 array [4] = 4 array [5] = 0 array [6] = 133441 array [7] = 0 array [8] = 0 array [9] = 0 Ok
Always remember to track the size of an array when referencing it. Store the array size in variables; do not hard-code the array size hard-code. Otherwise, if the identifier points to another array of different sizes later, but forgets to change the length of the hard-coded array, the program may have the array out of bounds.
3. String overflow
A string is just a specific type of array. In C, a string is an array of values of type char, where the end of the string is represented by a zero character.
Therefore, as with arrays, be careful not to go beyond the range of strings. It is sometimes called a string overflow.
Using the gets function to read data is a way to easily cause string overflows. The gets function is very dangerous because it doesn't know how much data can be stored in a string and only reads the data from the user mechanically. No accident occurs if the user enters a short string like foo, but when the value the user enters exceeds the length of the string, the consequences can be catastrophic.
The following is an example program that uses the gets function to read the city name. In this program, I also added some unused variables to show the impact of string overflows on other data:
# include # include int main () {char name [10]; / * Such as "Chicago" * / int var1 = 1, var2 = 2; / * show initial values * / printf ("var1 =% d; var2 =% d\ n", var1, var2); / * this is bad. Please don't use gets * / puts ("Where do you live?"); gets (name); / * show ending values * / printf ("is length% d\ n", name, strlen (name)); printf ("var1 =% d; var2 =% d\ n", var1, var2); / * done * / puts ("Ok"); return 0;}
When you test similar short city names, the program works well, such as Chicago in Illinois or Raleigh in North Carolina:
Var1 = 1; var2 = 2 Where do you live? Raleigh is length 7 var1 = 1; var2 = 2 Ok
The Welsh town of Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch has one of the longest names in the world. This string is 58 characters, far more than the 10 characters reserved in the name variable. As a result, the program stores values in other areas of memory, overriding the values of var1 and var2:
Var1 = 1; var2 = 2 Where do you live? Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch is length 58 var1 = 2036821625; var2 = 2003266668 Ok Segmentation fault (core dumped)
Before the end of the run, the program covers the rest of the memory with a long string. Notice that the values of var1 and var2 are no longer the starting 1 and 2.
Avoid using the gets function and use a more secure way to read user data. For example, the getline function allocates enough memory to store user input, so there is no unexpected string overflow due to the long value entered.
4. Repeatedly free memory
"the allocated memory should be released manually" is one of the good programming principles of C language. Programs can use the malloc function to allocate memory for arrays and strings, which opens up a block of memory and returns a pointer to the starting address in memory. The program can then use the free function to free memory, which uses pointers to mark memory as unused.
However, you should only use the free function once. A second call to free can have unintended consequences and may destroy your program. The following is a short example program for this point. The program allocates memory and immediately frees it. But in order to imitate a forgetful but organized programmer, I freed memory again at the end of the program, resulting in releasing the same memory twice:
# include # include int main () {int * array; puts ("malloc an array..."); array = malloc (sizeof (int) * 5); if (array) {puts ("malloc succeeded"); puts ("Free the array..."); free (array);} puts ("Free the array..."); free (array); puts ("Ok");}
Running this program results in a dramatic failure the second time you use the free function:
Malloc an array... Malloc succeeded Free the array... Free the array... Free (): double free detected in tcache 2 Aborted (core dumped)
Remember to avoid calling free multiple times on arrays or strings. Positioning the malloc and free functions in the same function is one way to avoid repeatedly freeing memory.
For example, a card game program might allocate memory for a deck of cards in the main function and then use the deck in other functions to play the game. Remember to free memory in the main function, not in other functions. Putting malloc and free statements together helps avoid freeing memory multiple times.
5. Use invalid file pointer
File is a convenient way to store data. For example, you can store the program's configuration data in a config.dat file. Bash shell reads the initialization script from .bash _ profile in the user's home directory. The GNU Emacs editor looks for the file .emacs to determine the starting value. The Zoom conferencing client uses the zoomus.conf file to read its program configuration.
Therefore, the ability to read data from a file is important to almost all programs. But what happens if the file you want to read doesn't exist?
To read a file in C, first open the file with the fopen function, which returns a stream pointer to the file. You can use this pointer to read data in combination with other functions, for example, fgetc will read the file character by character.
If the file to be read does not exist or the program does not have read permission, the fopen function returns NULL as the file pointer, indicating that the file pointer is invalid. But here is an example program that mechanically reads the file directly without checking whether fopen returns NULL:
# include int main () {FILE * pfile; int ch; puts ("Open the FILE.TXT file..."); pfile = fopen ("FILE.TXT", "r"); / * you should check if the file pointer is valid, but we skipped that * / puts ("Now display the contents of FILE.TXT..."); while ((ch = fgetc (pfile))! = EOF) {printf (", ch);} fclose (pfile) / * done * / puts ("Ok"); return 0;}
When you run this program, the first call to fgetc will fail and the program will abort immediately:
Open the FILE.TXT file... Now display the contents of FILE.TXT... Segmentation fault (core dumped)
Always check the file pointer to make sure it is valid. For example, after calling fopen to open a file, check the pointer with a statement like if (pfile! = NULL) to ensure that the pointer is available.
People make mistakes, and even the best programmers make programming mistakes. However, following the above guidelines and adding some additional code to check for these five types of errors can avoid the most serious C programming errors. Writing a few lines of code in advance to catch these errors may save you hours of debugging time.
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.