Does someone know how I can use dynamically allocated multi-dimensional arrays using C? Is that possible?
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- How to get the maximum of more than 2 numbers in V
- Faster loop: foreach vs some (performance of jsper
- Convert Array to custom object list c#
Basics
Arrays in c are declared and accessed using the
[]
operator. So thatdeclares an array of 5 integers. Elements are numbered from zero so
ary1[0]
is the first element, andary1[4]
is the last element. Note1: There is no default initialization, so the memory occupied by the array may initially contain anything. Note2:ary1[5]
accesses memory in an undefined state (which may not even be accessible to you), so don't do it!Multi-dimensional arrays are implemented as an array of arrays (of arrays (of ... ) ). So
declares an array of 3 one-dimensional arrays of 5 floating point numbers each. Now
ary2[0][0]
is the first element of the first array,ary2[0][4]
is the last element of the first array, andary2[2][4]
is the last element of the last array. The '89 standard requires this data to be contiguous (sec. A8.6.2 on page 216 of my K&R 2nd. ed.) but seems to be agnostic on padding.Trying to go dynamic in more than one dimension
If you don't know the size of the array at compile time, you'll want to dynamically allocate the array. It is tempting to try
which should work if the compiler does not pad the allocation (stick extra space between the one-dimensional arrays). It might be safer to go with:
but either way the trick comes at dereferencing time. You can't write
buf[i][j]
becausebuf
has the wrong type. Nor can you usebecause the compiler expects
hdl4
to be the address of an address of a double. Nor can you usedouble incomplete_ary4[][];
because this is an error;So what can you do?
Do the math yourself
Simply compute memory offset to each element like this:
Allocate and do the work in a function
Define a function that takes the needed size as an argument and proceed as normal
Of course, in this case
ary4
is a local variable and you can not return it: all the work with the array must be done in the function you call of in functions that it calls.An array of pointers
Consider this:
Now
hdl5
points to an array of pointers each of which points to an array of doubles. The cool bit is that you can use the two-dimensional array notation to access this structure---hdl5[0][2]
gets the middle element of the first row---but this is none-the-less a different kind of object than a two-dimensional array declared bydouble ary[3][5];
.This structure is more flexible then a two dimensional array (because the rows need not be the same length), but accessing it will generally be slower and it requires more memory (you need a place to hold the intermediate pointers).
Note that since I haven't setup any guards you'll have to keep track of the size of all the arrays yourself.
Arithmetic
c provides no support for vector, matrix or tensor math, you'll have to implement it yourself, or bring in a library.
Multiplication by a scaler and addition and subtraction of arrays of the same rank are easy: just loop over the elements and perform the operation as you go. Inner products are similarly straight forward.
Outer products mean more loops.
With dynamic allocation, using malloc:
This allocates an 2D array of size
dimension1_max
*dimension2_max
. So, for example, if you want a 640*480 array (f.e. pixels of an image), usedimension1_max
= 640,dimension2_max
= 480. You can then access the array usingx[d1][d2]
whered1
= 0..639,d2
= 0..479.But a search on SO or Google also reveals other possibilities, for example in this SO question
Note that your array won't allocate a contiguous region of memory (640*480 bytes) in that case which could give problems with functions that assume this. So to get the array satisfy the condition, replace the malloc block above with this:
Here is working code that defines a subroutine
make_3d_array
to allocate a multidimensional 3D array withN1
,N2
andN3
elements in each dimension, and then populates it with random numbers. You can use the notationA[i][j][k]
to access its elements.