Multi-dimensional static and dynamic array storage and access
I. first look at the following section of code for allocating multidimensional static arrays.
# Include <iostream>
Using namespace STD;
Int main (INT argc, char * argv [])
{
Char sz_temp [3] [3]; // allocate a static two-dimensional array
Char (* sz) [3] = NULL; // pointer Initialization
SZ = (char (*) [3]) sz_temp; // declare a pointer to a one-dimensional array. It is mainly used to access rows in a two-dimensional array.
Strcpy (* (SZ + 1), "ABC"); // copy data
Return 0;
}
Discussion:
Some people will say that the above Code is so simple that it is introduced in Tan's book ~, It is indeed relatively simple. It is only a prerequisite for comparison.
Next, let's take a look at its address distribution chart:
We can see that it can be used to access rules by dimension (for example, SZ [2] [2], SZ [1] [3]); however, we can also use SZ [0] [1], SZ [0] [3], SZ [0] [5]…. Until SZ [0] [9], we can see in the address that their storage process is continuous: store in the order of element existence. From 0 ~ 9.
2. Now let's take a look at a piece of code about Multidimensional Dynamic Array allocation.
# Include <iostream>
Using namespace STD;
Int main (INT argc, char * argv [])
{
Int COUNT = 5;
Char ** sz_temp = (char **) malloc (count) * sizeof (char *));
Char (* sz) [20] = NULL;
For (INT idx = 0; idx <count; idx ++)
{
Sz_temp [idx] = (char *) malloc (20 * sizeof (char ));
}
SZ = (char (*) [20]) sz_temp; // converts sz_temp to a pointer pointing to an array of 20 char elements.
Strcpy (* (SZ + 1), "ABC"); // Error?
Free (sz );
Return 0;
}
Discussion:
First look at the following address diagram:
(This figure shows everything)
SZ is now converted. Although its starting address still starts with the address sz_temp, SZ regards the dynamically allocated array as an array for storing char, that is, in SZ's eyes, the space allocated by sz_temp occupies the space of the char element, and it moves 20 char addresses (because the type is (char (*) [20]). Again, accessing sz_temp through SZ will no longer show the pointer feature. It only contains char data (replace pointer storage with Char ), because one char is 1 bytes and the size of one pointer is 4 bytes:
SZ + 1 => sz_temp + 5 // 20*1 and 5*4. Therefore, we can see that the address of SZ + 1 is the same as that of sz_temp + 5, strcpy (* (SZ + 1), "ABC"); it writes the address after SZ + 1 to ABC, & SZ [0] [4] corresponds to sz_temp + 1, which is also the same address.
Some may ask: why does "SZ = (char (*) [20]) sz_temp;" have been used in both static and dynamic allocation?
The reason is as follows:
1. for SZ = (char (*) [20]) sz_temp in a static array, sz_temp itself is the first row pointing to a two-dimensional array by default, just like a one-dimensional array, pointing to the first element is the same thing. If we replace SZ = (char (*) [20]) sz_temp; in the first example with SZ = sz_temp; then it is correct, the sz_temp format itself is (char (*) [20]) type, and there is no need to convert it.
2. for SZ = (char (*) [20]) sz_temp in a dynamic array; Because sz_temp is not the name of a two-dimensional array, It is a pointer, therefore, there is no such feature as mentioned in Article 1st, which can represent rows in a two-dimensional array. Therefore, when converting, SZ will put (char (*) [20]) sz_temp; the dynamic array is regarded as a row in a two-dimensional array. When SZ accesses the dynamic array, it regards all elements in the dynamic array allocated by sz_temp as char data, so the address of SZ + 1 is the same as that of sz_temp + 5.
3. note that the array name address in the static array is the same as the address of the first line and the address of the first element; the pointer address pointing to the dynamic array is not the address of the dynamic array, which must be clarified.
Hey, the source of this problem is the problem of a netizen on csdn. Now let's look at the solution ~
# Include <iostream>
Using namespace STD;
Typedef char (* chararrp) [20];
Void fun (chararrp arraylist)
{
Strcpy (* (arraylist), "ABC"); // OK, it is right.
}
Int main (INT argc, char * argv [])
{
Int COUNT = 5;
Char ** sz_temp = (char **) malloc (count) * sizeof (char *));
Chararrp SZ = NULL;
For (INT idx = 0; idx <count; idx ++)
{
Sz_temp [idx] = (char *) malloc (20 * sizeof (char ));
}
For (INT I = 0; I <count; ++ I)
{
SZ = (chararrp) sz_temp [I];
Fun (sz );
/*
1. SZ = (chararrp) sz_temp [I]; it converts the pointer value of the I element in sz_temp to (* chararrp) [20], to point to a one-dimensional array containing 20 elements. In this way, fun (sz); can call the matching function.
2. because the dynamic allocation of 20 elements is a group of 5 segments of memory, the segments are continuous, and the segments are non-consecutive, the access is not allowed in SZ + N mode, sz_temp [idx] = (char *) malloc (20 * sizeof (char); its allocation does not follow the address & sz_temp [idx-1] [19.
*/
}
Free (sz );
Return 0;
}