When using scanf, you must note that the address operator &This operator is easy to forget, and will cause a memory conflict. The error is hard to find and serious. See the following code:
int i = 2; scanf_s("%d", i);
The above code accidentally loses the & operator [S1], and the following conflict will occur (I was previously assigned 2 values, so it is an access conflict at the position 0x00000002. If no value is assigned, an access conflict occurs in 0xcccccccc)
In C, the compiler allocates different memory space for variables due to different dependent variable types.. When using scanf, you must provide the memory address of the variable and ensure that the space to be assigned is correct, so we can use this to discuss the relationship between variable types, variable names, and memory. The variable types in C are divided into the following situations:
Basic Value Type:
For example, if int I is declared, memory [s2] is allocated for I in this sentence, but this memory has not been initialized. You can use this memory directly through & I.
int i; scanf_s("%d", &i);
For basic data types, such as int, Char, float, and double, space is allocated during the Declaration, so there is no need to worry about memory access conflicts. The construction type and pointer type are not the same as the space allocation time.
Int * Pi, char * PC, and other pointer types:
Declaring int * PI allocates storage space for pi, but does not allocate space for pi. In this case, it is easy to create a wild pointer. The following code shows a common mistake made by a newbie:
char *pc; scanf("%c", pc);
In this case, the initialization error is also encountered.
The position 0xccccccc refers to the PC. In the char * PC statement, the storage space is opened for the pointer PC, but the PC is not pointed to a safe location. This is what we often call the wild pointer. The detailed analysis below will be a bit difficult, but it will be helpful to understand it carefully.
PCThis name represents the address. Unlike the common variable name, the common variable name represents the value stored in an address, the method for obtaining the addresses and values of these two variables is very different. For common variablesI,IIt represents the value stored in this memory segment. The address retrieval must be performed by means of the access token.& I; For pointer VariablesPi,PiIt representsPiThe address pointing to the memory. To obtain the value, you must use the value symbol.* Pi.(AsPiIs a variable name, which does not occupy space.PiThe address to be pointed to is to be stored, and space should be allocated for this address(Yes& PI)It sounds like a mess, so you can understand and digest it.).Char* PiIs allocated& PC, But not* PCAllocate space.Therefore, the above error occurs.
Run char * PC based on the value of the local variable during compilation. Sentence:
Correction MethodObviously, point the pointer PC to a safe space. You can open up a space by yourself, or declare a required type of common variable to assign its address to this pointer, or assign a value to null. The following code uses the second method:
char c; char *pc; pc = &c;
Records the local variables when these three statements are executed:
In Pc = & C;, point the pointer PB to the address of variable C, which is not a wild pointer. Next, let's take a look at the corrected code and analysis of various addresses and stored values. First, let's look at the complete code:
Char c = 'P'; char * PC; Pc = & C; scanf ("% C", PC); // consistent between upper and lower display, enter the character P printf here ("the IP address of the pointer PC is & PC: % d \ n", & PC); printf ("the IP address of the pointer PC is PC: % d \ n ", PC); printf (" the character address is & C: % d \ n ", & C ); printf ("the IP address pointed to by the pointer PC can also be expressed as & * PC: % d \ n", & * PC ); printf ("the data stored in the pointer PC pointing to the address is * PC: % C; the same as the character value C: % C \ n", * PC, C );
The running result is:
Note the address of the PC that we do not usually care about (rather than the address pointed to by the Commonly Used PC), which is helpful for analyzing the memory allocation problem. Like normal variables, we need a piece of memory to store pointers, that is, & PC.
Array int I []:
When writing code, you must have written code such as int I [] and int I [5. If you write only int I [];, an error is returned. Because it is declared that the memory is to be allocated without specifying the size of the array, the compiler does not know how much memory to allocate, so an error is reported.
Return to the topic. What will happen if the following code is used?
char c[5];scanf("%c", &c[0]);
Of course it was successful. Char C [5]; the sentence is allocated with five char spaces, the names are C [0], C [1], C [2], C [3], and C [4]. then, take one of the addresses & C [0] for the operation.
Here, there is nothing more than whether there is a memory allocation and how to retrieve the address.CWhen declaring a variable, it allocates the memory space for the variable. However, it should be noted that the memory space is allocated.The preceding section analyzes common variables, pointer variables, and arrays. Let's look at struct again:
Struct type
First, let's look at a piece of code. The following Code defines a struct and declares a variable of this type:
struct person { int age; char sex; }; struct person p; scanf("%c", &p.sex);
What happens when the above code is executed? Analyze memory allocation and values: struct person P; declare a variable and allocate memory for it; then access to memory, P. sex itself is a char type and is a common variable. Therefore, it is no problem to use & access. Run this code and pass it smoothly. Let's look at the memory address analysis of the above Code:
Indeed, when declaring struct person P, we allocated addresses for each volume.
A mix of struct and pointer types
The above analyzes the case of a separate pointer. When declaring a pointer char * PC, only the pointer PC itself to be stored is allocated space, no processing is performed for the space x pc pointed to by the pointer, which makes the PC a wild pointer. What if the pointer is combined with struct or array? The principle is the same for the two cases. Take struct as an example and run the following code:
struct person{ int age; char sex;};struct person *p;
Defines a struct person and declares a pointer P pointing to the person type. Here, struct person * P. The sentence is to allocate an address for the pointer P and specify the address pointed to by the pointer.
So we still need to do this to allocate space for P:
p = (struct person*)malloc(sizeof(struct person));[s3]
Then you can use p. Find the variable name (* P). sex that we need to assign a value, and then find the address of this variable name & (* P). Sex:
scanf("%c", &(*p).sex);
Analyze the addresses:
P represents the address of the struct, so it is the same as the address of the first data structure. Age in the struct.
Finally, let's talk about scanf_s in:
Use vs2010 to compile the following code:
int i;scanf_s("%d", &i);
The system prompts that scanf is not safe enough. We recommend that you use the scanf_s function. Scanf, which is used in most textbooks, is rather confusing. It was found that scanf is a standard input function defined in ansi c, but it does not perform a boundary check during reading, which may cause memory leakage. Therefore, the vs series of Ms provides the scanf_s function. During the call, a parameter must be provided to indicate the number of characters that are read multiple times. In this way, the boundary check is performed in disguise.
[S1]
Here we should also describe the data type of the result obtained by the & operator "&". This is a pointer type, so an error of Type mismatch may occur if an int A = & I; cannot be defined.
When we use common pointers, The & operator is exactly the same.
int *p;p = &i;
[S2]
Is the memory allocation time in the compilation or link phase?
The following are the information on the network, which is easy to digest:
Space allocation during compilation refers to static space allocation (as opposed to dynamically applying for space with new), such as global variables or static variables (including some complex types of constants ), the size of the required space can be clearly calculated and will not be changed. Therefore, they can be directly stored in a specific section of the executable file (including the initialization value ), when the program is running, it directly loads this Section into a specific segment, without the need to use additional code to generate these variables during the program.
In fact, the concept of "variable" is no longer available for so many attributes (such as names, types, scopes, and lifetime) during compilation ), the corresponding memory is only one block (only the first address and size). Therefore, the space dynamically applied during runtime requires additional code maintenance to ensure that different variables do not mix the memory. For example, writing new indicates that a piece of memory is occupied, and other variables cannot be used. Writing Delete indicates that the memory is free and can be used by other variables. (We usually use the memory through variables. For encoding, variables give names to memory blocks to distinguish them from each other)
The time for memory application and release is very important. Data will be lost too early, and memory will be consumed too late. In specific circumstances, the compiler can help us complete this complex task (adding additional code to maintain memory space for application and release ). In this sense, the compiler is also responsible for allocating space for local automatic variables. Further, memory management uses the heap and stack data structures that we often talk about.
Finally, you can understand the not rigorous statement of "allocating space by the compiler" as it planned the memory usage scheme for these variables during compilation, this solution is written into an executable file (the file contains a number of code not derived from your brain) and is not executed until the program runs!
[S3]
Malloc returns the void * type, so we need to forcibly convert it to the int * type we need;
The size_t type returned by sizeof is tepedef in <stddef. h> and is a machine-related definition.