Obtain a dynamic two-dimensional array

Source: Internet
Author: User

In the C language, there are built-in one-dimensional arrays, two-dimensional arrays and other multi-dimensional arrays, you can also use the Dynamic Allocation of memory, it is easy to get

Similar to the dynamic array with built-in static one-dimensional array (here I call this, this definition may not exist), but how to obtain dynamic two-dimensional

What about data groups? If you understand how to access the array pointer in C language, it is very easy to implement a two-dimensional array.

The following describes how to access one-dimensional data pointers:

Suppose the definition is as follows:

# Define dims 10

Int arr1 [dims]

Int * parr1;

 

Anyone who has learned the C language knows that every element of the data can be accessed as follows:

Arr1 [I] = xxxx;

You can also understand data as a pointer:

Parr1 = arr1;

For (INT I = 0; I <dims; ++ I)

{

* Parr1 = xxxx;

Parr1 ++;

}

This is a one-dimensional scenario. What about two-dimensional scenarios?

Static 2D arrays and 3D arrays are convenient.

Int arr2 [dims] [dims];

Int * parr2;

For (INT I = 0; I <dims; ++ I)

{

For (Int J = 0; j <dims; ++ J)

{

Arr2 [I] [J] = xxxx; // access the array Unit

}

}

Parr2 = arr2;

For (INT I = 0; I <dims * dims; ++ I)

{

* Parr2 ++ = xxxx; // access the array unit and move the pointer down

}

In C, static multidimensional data is actually a plane data. The C language compiler translates data access

Memory Access.

For example:

One-dimensional: arr1 [I] ----> * (arr1 + (I * sizeof (arr1 [0])

Two-dimensional: arr2 [I] [J] ---> * (arr2 + (I * sizeof (arr2 [0] [0]) + N * sizeof (arr2 [0] [0])
Here, n is the maximum value of the second submark of two-dimensional data.

3D: similar to the preceding method, it starts with the first address of the array and calculates the data offset.
The subscript uses arrays to give people a clear feeling. The two methods can increase the complexity of writing programs, which means reducing the chance of errors.
In some cases, the use of Static Two-dimensional data has its limitations. When the size is unknown, it is inconvenient to use static arrays.

In this case, it will consume stack resources (static arrays are allocated in the stack), so dynamic arrays are required. For one-dimensional situations, it can be like a one-dimensional static number.

For multi-dimensional arrays, if only the space required by elements is allocated as a static array, the subscript method cannot be used.

Access data.
Int * parr1, ** parr2;
Parr1 = (int *) malloc (sizeof (INT) * dims );
Parr2 = (INT **) malloc (sizeof (INT) * dims );
...
Parr1 [I] = xxx; // correct
Parr2 [I] [J] = xxx; // Error

Why is there a problem with the two dimensions?
Let's take a look at the definition of disassembly:
65: parr2 [4] [5] = 10;
004011b8 mov eax, dword ptr [ebp-4]; ebp-4 is variable int ** parr2
004011bb mov ECx, dword ptr [eax + 10 h]; 10 h = 4 * sizeof (INT) = 4*4
004011be mov dword ptr [ECx + 14 h], 0ah; 14 h = 5*4
These three lines of assembly are generated under vc6.0.
The first line stores the variable address in eax, then moves eax to the fourth offset to ECx, and then obtains the data in the second position.

It can be parsed as follows:
(Parr2 [4]) [5]
Let's take a look at the assembly code of Static Two-Dimensional Data:
64: arr2 [4] [5] = 10;
004011ae mov dword ptr [ebp-0DCh], 0ah; 0dch = [(10-1)-4] * 40 + (5-1) * 4-4
Compared with the above, the method here is quite different. Static Two-dimensional data is directly accessed, but the dynamic method, C language is not considered as an array

But regard it as a secondary indirect.
With the above foundation, I think the reader will soon know how to implement a dynamic two-dimensional data.
First, create a row pointer, pointer row data, and then return the row pointer as a two-dimensional data pointer.
Below:

In this way, there is a problem. To apply for a two-dimensional array, We need to allocate space multiple times, which will generate memory fragments. If I think of one

Memory Allocation Method. As follows:


The final implementation code is as follows:
Dyn2dimarr. h
-------------------------
# Ifndef _ dyn2dimarr_header_h __< br/> # DEFINE _ dyn2dimarr_header_h __</P> <p>/** <br/> * obtain a dynamic two-dimensional array, you can use the [I] [J] method to access <br/> * return a two-dimensional Data Pointer <br/> */<br/> void ** getdyn2dimarr (INT m, int N, int element_size ); </P> <p>/** <br/> * release two-dimensional data memory <br/> */<br/> void freedyn2dimarr (void ** parr2 ); <br/> # endif //~ _ Dyn2dimarr_header_h__< br/>

Dyn2dimarr. c
-------------------------
# Include <stdlib. h> <br/> # include <string. h> <br/> # include <assert. h> </P> <p> # include "dyn2dimarr. H "</P> <p> void ** getdyn2dimarr (int m, int N, int element_size) <br/>{< br/> void * pmem = NULL; <br/> void ** pmemowner = NULL; <br/> int pt_size; <br/> int user_size, owner_size, line_size; <br/> int I; <br/> assert (M> 0 & n> 0); <br/> assert (element_size> 0); </P> <p> line_size = N * element_size; <br/> user_size = m * line_size; <br/> pt_size = sizeof (void *); <br/> owner_size = pt_size * m; <br/> pmem = malloc (user_size + owner_size); <br/> If (pmem = NULL) return NULL; <br/> memset (pmem, 0, user_size + owner_size); <br/> // it is meaningful to convert it to void ** here, because the void * <br/> // operation cannot be implemented in ansi c, although it is possible in gnu c, however, if char * is used as the calculation size <br/> // convert it to void **, it is equivalent to a pointer operation on a pointer, that is, the offset is <br/> // the size of a pointer. Here we cannot assume that the size is 4, because on a 64-bit platform, pointer size: 8 <br/> pmemowner = (void **) pmem + user_size/pt_size; <br/> for (I = 0; I <m; ++ I) <br/> {<br/> pmemowner [I] = (void **) pmem + (I * line_size/pt_size ); <br/>}</P> <p> return pmemowner; <br/>}</P> <p> void freedyn2dimarr (void ** parr2) <br/> {<br/> // It is advantageous to release your memory, if you use other methods for internal allocation in the future, <br/> // you do not need to modify the customer code. You can also avoid knowing that the customer is a one-dimensional pointer. <br/> free (parr2 [0]); <br/>}

Well, the two-dimensional dynamic array has been implemented. Will someone ask about the three-dimensional dynamic array? I think the implementation principle is already here. The problem should not be too big.

For ease of use, the test code is pasted here in a usable way.

# Include <stdio. h> <br/> # include <stdlib. h> </P> <p> # include "dyn2dimarr. H "</P> <p> int main (INT argc, char ** argv) <br/> {<br/> int ** arr2; <br/> int * arrline; <br/> int * pdata; <br/> int I, j; <br/> arr2 = (INT **) getdyn2dimarr (8, 10, sizeof (INT); <br/> for (I = 0; I <8; ++ I) {<br/> for (j = 0; j <10; ++ J) {<br/> arr2 [I] [J] = I <8 | J; <br/>}</P> <p> printf ("using arr2 [I] [J] mode/N "); <br/> for (I = 0; I <8; ++ I) {<br/> for (j = 0; j <10; ++ J) {<br/> printf ("(% d, % d)", arr2 [I] [J]> 8, arr2 [I] [J] & 0xff ); <br/>}< br/> printf ("/N"); <br/>}< br/> printf ("/N "); </P> <p> printf ("use arr2 [I] to obtain the row pointer arrline, and then use the arrline [J] method/N "); <br/> for (I = 0; I <8; ++ I) {<br/> arrline = arr2 [I]; <br/> for (j = 0; j <10; ++ J) {<br/> printf ("(% d, % d)", arrline [J]> 8, arrline [J] & 0xff); <br/>}< br/> printf ("/N "); <br/>}< br/> printf ("/N"); </P> <p> printf ("use arr2 [I] to obtain the row pointer arrline, then use * arrline + offset mode/N "); <br/> for (I = 0; I <8; ++ I) {<br/> arrline = arr2 [I]; <br/> for (j = 0; j <10; ++ J) {<br/> printf ("(% d, % d)", * arrline> 8, * arrline & 0xff); <br/> ++ arrline; <br/>}< br/> printf ("/N"); <br/>}< br/> printf ("/N "); </P> <p> printf ("Get Data Pointer using arr2 [0] and directly access all data using full offset/N "); <br/> pdata = arr2 [0]; // arr2 cannot be used directly here, which is different from a static two-dimensional array <br/> for (I = 0; I <8; ++ I) {<br/> for (j = 0; j <10; ++ J) {<br/> printf ("(% d, % d) ", * pdata> 8, * pdata & 0xff); <br/> ++ pdata; <br/>}< br/> printf ("/N"); <br/>}</P> <p> freedyn2dimarr (arr2 ); <br/> arr2 = NULL; <br/> return 0; <br/>}< br/>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.