5

I was thinking of writing a function that takes n parameters and returns an n-dimensional array using those parameters as the dimensions. Now i realize an one-d and 2d array is easy to implement with pointers. For 2d array the snippet would be something like (standard way) :

int** x;
int* temp;

x = (int**)malloc(m * sizeof(int*));
temp = (int*)malloc(m*n * sizeof(int));
for (int i = 0; i < m; i++) {
  x[i] = temp + (i * n);
}

where the array is of size m*n; But the problem lies how do we find the nested loop parameters for a n-dimensional array? Is there any way to optimize the code?

shortCircuit
  • 169
  • 2
  • 10
  • 3
    [Do not cast the result of malloc in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Paul R Nov 09 '13 at 21:53
  • 5
    well, i found all the books doing this. I'm in learning phase now. :) – shortCircuit Nov 09 '13 at 21:57
  • 1
    If those books are by Kanetkar then throw them away and get one or two decent books by reputable authors. – Paul R Nov 09 '13 at 22:07
  • You can extend the idea to 3 and 4 d arrays but for a general n it gets harder. Also, how would reference the array once you had it? You couldn't a[][][]...[] in your code because n is not known during compile time. I think you could allocate and build such a beast but I don't know how you would deference it without using some loop that probably involves void*'s. – Charlie Burns Nov 09 '13 at 22:27
  • i was thinking like this, for k-dimension, a for loop runs from i=0 to k^k -1 then for each i there would be a malloc who would allocate a size of how much?? i got stuck again . :) – shortCircuit Nov 09 '13 at 22:54

2 Answers2

11

This shows how to create an N-dimensional array and how to index its elements. These provide the basic mechanisms needed. This is something students consider when learning, but it is rarely used in practice. There are usually better ways to organize data structures. Additionally, most useful algorithms would have patterns in how they traverse the data, so it would be better to build code that updates indices efficiently in an incremental manner rather than recalculating them from scratch as shown below.

/*  Note:  For demonstration purposes only.  Depending on needs, other types
    might be used for indices and sizes, and the array type might be wrapped
    in an opaque struct rather than exposed as "int *".
*/


//  Create an array with N dimensions with sizes specified in D.
int *CreateArray(size_t N, size_t D[])
{
    //  Calculate size needed.
    size_t s = sizeof(int);
    for (size_t n = 0; n < N; ++n)
        s *= D[n];

    //  Allocate space.
    return malloc(s);
}

/*  Return a pointer to an element in an N-dimensional A array with sizes
    specified in D and indices to the particular element specified in I.
*/
int *Element(int *A, size_t N, size_t D[], size_t I[])
{
    //  Handle degenerate case.
    if (N == 0)
        return A;

    //  Map N-dimensional indices to one dimension.
    int index = I[0];
    for (size_t n = 1; n < N; ++n)
        index = index * D[n] + I[n];

    //  Return address of element.
    return &A[index];
}

Example of use:

//  Create a 3*3*7*7*9 array.
size_t Size[5] = { 3, 3, 7, 7, 9 };
int *Array = CreateArray(5, Size);

//  Set element [1][2][3][4][5] to -987.
*Element(Array, 5, Size, (size_t []) { 1, 2, 3, 4, 5 }) = -987;
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • where can i find these better ways. aalthough it seems like its getting tougher. :) – shortCircuit Nov 09 '13 at 22:59
  • @shortCircuit: The better ways to organize a data structures depends on the uses to which the data will be put. – Eric Postpischil Nov 09 '13 at 23:00
  • off the record, what would malloc (i1*i2*..in * sizeof(int *)) give me. @Eric – shortCircuit Nov 09 '13 at 23:20
  • @shortCircuit: I do not understand the question. No `int *` objects are dynamically allocated in this code, so no size is computed using `sizeof(int *)`. Are you asking what `malloc` returns? Are you asking how much space that expression allocates? – Eric Postpischil Nov 09 '13 at 23:32
  • VS-2012 dont allow to initialize with Element() In this case...how can i initialize all array element with for loop??? – AminM Jan 19 '14 at 14:49
2

I prefer not to use multidimensional arrays, use 1D instead:

int* pArray = (int*) malloc(m * n * sizeof(int*));

// access pArray[a][b]
int result = pArray[a*m + b];
Hhyperion
  • 666
  • 5
  • 6