In C ++/C Programs, pointers and arrays can be replaced with each other in many places, which leads to the illusion that the two are equivalent. But there are essential differences between the two:
Array: either created in a static storage area (such as a global array) or on a stack. The array name corresponds to (rather than pointing to) a piece of memory, and its address and capacity remain unchanged during the lifetime, only the content of the array can be changed.
Pointer: it can point to any type of memory block at any time. It is characterized by "variable", so we often use pointers to operate dynamic memory. Pointers are far more flexible than arrays, but they are more dangerous.
The following uses a string as an example to compare the features of pointers and arrays:
(1) modification content
In instance 1 code, the size of character array a is 6 Characters and its content is hello. The content of A can be changed, for example, a [0] = 'x '. The pointer P points to the constant string "world" (in the static storage area with the content of World). The content of the constant string cannot be modified. In terms of syntax, the compiler does not think that the statement P [0] = 'X' is inappropriate, but this statement attempts to modify the content of the constant string and causes a running error.
Instance 1 modify the array and pointer content
Char A [] = "hello ";
A [0] = 'X ';
Cout <A <Endl;
Char * P = "world"; // note that P points to a constant string
P [0] = 'X'; // the compiler cannot find this error.
Cout <p <Endl;
(2) content replication and Comparison
The array name cannot be directly copied or compared. In Example 2, if you want to copy the content of array a to array B, you cannot use statement B = A. Otherwise, a compilation error will occur. Use the standard library function strcpy for replication. Similarly, if the content of B and A is the same, it cannot be determined by if (B = A). The standard library function strcmp should be used for comparison.
In pointer applications, statement P = A does not copy the content of A, but assigns the address of A to P. To copy the content of A, use the library function malloc as P to apply for a memory with a capacity of strlen (A) + 1 characters, and then use strcpy to copy strings. Similarly, the statement if (P = A) compares not the content but the address, and should be compared using the database function strcmp.
Copy and compare the array and pointer content of instance 2
// Array...
Char A [] = "hello ";
Char B [10];
Strcpy (B, A); // B = A cannot be used;
If (strcmp (B, A) = 0) // If (B = A) cannot be used)
...
// Pointer...
Int Len = strlen ();
Char * P = (char *) malloc (sizeof (char) * (LEN + 1 ));
Strcpy (P, A); // do not use P =;
If (strcmp (P, A) = 0) // do not use if (P =)
...
(3) computing memory capacity
The sizeof operator can be used to calculate the array capacity (number of bytes ). In Example 3 (a), the value of sizeof (a) is 12 (do not forget ''). The pointer P points to A, but the value of sizeof (P) is 4. This is because sizeof (p) obtains the number of bytes of a pointer variable, which is equivalent to sizeof (char *) rather than the memory capacity referred to by P. C ++/C language cannot know the memory capacity referred to by the pointer unless you remember it when applying for memory. Note: When an array is passed as a function parameter, the array will automatically degrade to a pointer of the same type. In Example 7-3-3 (B), sizeof (a) is always equal to sizeof (char *) regardless of the size of array *).
Instance 3 (a) calculates the memory capacity of arrays and pointers
Char A [] = "Hello World ";
Char * P =;
Cout <sizeof (a) <Endl; // 12 bytes
Cout <sizeof (p) <Endl; // 4 bytes
Instance 3 (B) array degrades to pointer
Void func (char a [1, 100])
{
Cout <sizeof (a) <Endl; // 4 bytes instead of 100 bytes
}
(4) How does the pointer Parameter Pass the memory?
If the function parameter is a pointer, do not expect this pointer to apply for dynamic memory. In Example 4 (a), the getmemory (STR, 200) Statement of the test function does not enable STR to obtain the expected memory. STR is still null. Why?
Instance 4 (a) tries to apply for dynamic memory with pointer Parameters
Void getmemory (char * P, int num)
{
P = (char *) malloc (sizeof (char) * num );
}
Void test (void)
{
Char * STR = NULL;
Getmemory (STR, 100); // STR is still null
Strcpy (STR, "hello"); // running error
}
The fault lies in the getmemory function. The compiler always needs to make a temporary copy for each parameter of the function. The copy of the pointer parameter P is _ p, and the compiler makes _ p = P. If the program in the function body modifies the content of _ p, the content of parameter P is modified accordingly. This is why pointers can be used as output parameters. In this example, _ P applied for a new memory, but changed the memory address indicated by _ p, but P was not changed at all. Therefore, the getmemory function cannot output anything. In fact, each execution of getmemory will leak a piece of memory, because the memory is not released with free.
If you need to use the pointer parameter to request memory, you should use "pointer to Pointer" instead. See example 4 (B)
Instance 4 (B) uses a pointer to the pointer to request dynamic memory
Void getmemory2 (char ** P, int num)
{
* P = (char *) malloc (sizeof (char) * num );
}
Void Test2 (void)
{
Char * STR = NULL;
Getmemory2 (& STR, 100); // note that the parameter is & STR, not Str
Strcpy (STR, "hello ");
Cout <STR <Endl;
Free (STR );
}
Because the concept of "pointer to Pointer" is not easy to understand, we can use function return values to transmit dynamic memory. This method is simpler. See example 4 (c)
Instance 4 (c) transmits dynamic memory with function return values
Char * getmemory3 (INT num)
{
Char * P = (char *) malloc (sizeof (char) * num); // return the address in the heap.
Return P;
}
Void test3 (void)
{
Char * STR = NULL;
STR = getmemory3 (100 );
Strcpy (STR, "hello ");
Cout <STR <Endl;
Free (STR );
}
Although it is easy to use the function return value to pass dynamic memory, some people often use the return statement wrong. It is emphasized that the return statement should not be used to return the pointer pointing to the "stack memory", because the function exists in the memory and automatically disappears at the end of the function. See example 4 (d)
Instance 4 (d) Return Statement returns pointer to "stack memory"
Char * getstring (void)
{
Char P [] = "Hello World"; // return the address in the stack
Return P; // the compiler will give a warning
}
Void test4 (void)
{
Char * STR = NULL;
STR = getstring (); // STR content is junk
Cout <STR <Endl;
}
Use the debugger to track test4 step by step. After executing the STR = getstring statement, STR is no longer a null pointer, but the STR content is not "Hello World" but garbage.
What if I rewrite Example 4 (d) to Example 4 (e?
Instance 4 (e) Return Statement returns a constant string
char *GetString2(void)
{
char *p = "hello world";
return p;
}
void Test5(void)
{
char *str = NULL;
str = GetString2();
cout<< str << endl;
}
Although the function test5 runs without errors, the design concept of the function getstring2 is incorrect. Because "Hello World" in getstring2 is a constant string located in the static storage zone, it remains unchanged during the lifetime of the program. No matter when getstring2 is called, it returns the same read-only memory block.