How to declare a variable size 2D array in C?

17,593

Solution 1

If you have a modern C compiler (at least C99) in function scope it is as simple as:

unsigned arr[n][m];

this is called a variable length array (VLA). It may have problems if the array is too large. So if you have large images you could do:

unsigned (*arr)[m] = malloc(sizeof(unsigned[n][m]));

and later

free(arr);

Solution 2

If you need the memory to be contiguous, you have a couple of choices.

You could dynamically allocate a single block of memory, and then compute your offsets manually, like so:

size_t rows, cols;
...
int *arr = malloc(sizeof *arr * rows * cols);
...
arr[i * rows + j] = ...; // logically equivalent to arr[i][j]

You could set up a second array of pointers into the main array:

int **arrp = malloc(sizeof *arrp * rows);
...
for (i = 0; i < rows; i++)
  arrp[i] = &arr[i * rows];
...
arrp[i][j] = ...;

remembering that you would have to free both arr and arrp.

If you have a C99 implementation, you can just set up a pointer to a VLA, like so:

int (*arrp)[cols] = (int (*)[cols]) arr;
...
arrp[i][j] = ...;

Note that in this case, you're not allocating any memory for a secondary array, nor do you need to manually compute pointers into the main array; all you have to do is set arrp to the same location as arr and let the rules of pointer arithmetic do all the work.

If the images aren't that big, you could just set up a VLA (again, C99 or later):

int arr[rows][cols];

but in practice this isn't a good idea; stack frames are usually pretty limited in size.

Share:
17,593
Admin
Author by

Admin

Updated on July 19, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a problem with a project. I have to make a variable size 2D array for storing some prediction error..so this is about images. The trouble is that I have to load images of different sizes so for each image I would have to get into a file the 2D array with the coresponding number of pixels..I've searched among your questions but it's not what I'm looking for.Can anyone help me?

    Thank you

  • Akshaya Shanbhogue
    Akshaya Shanbhogue about 12 years
    Certainly not, but you can make it behave like an array
  • Jens Gustedt
    Jens Gustedt about 12 years
    Why using an emulation of an 2D array when you simply can use one?
  • Akshaya Shanbhogue
    Akshaya Shanbhogue about 12 years
    Well, that's the limitation of native C. Dynamic array creation, or memory allocation in general was a major flaw in C that made people turn away. It's still a good language as it gives raw power. This example proves the kinda of low-level manipulations you can do to achieve the desired results..
  • Yavar
    Yavar about 12 years
    Remember that variable length array mentioned above will be allocated on stack. Second thing which is not very relevant to the question is that C++ 0X does not support this feature (however since this is a C question so works fine)
  • Jens Gustedt
    Jens Gustedt about 12 years
    @Yavar, well that's why I also mentioned the version that is allocated with malloc. And even then it is a "variably modified type". And C++ clearly has other ways to do multidimensional arrays, so yes, this is not relevant at all.
  • Jens Gustedt
    Jens Gustedt about 12 years
    But still you didn't answer my question. C has dynamically allocated multidimensional arrays. Why in the world you would emulate a feature that the language provides?
  • Akshaya Shanbhogue
    Akshaya Shanbhogue about 12 years
    I am afraid you're wrong. I don't know about C99 standards but the older versions such as K&RC (The original) did not support stuff like "int a[m][n];" <<- m and n must be known at compile time.
  • Akshaya Shanbhogue
    Akshaya Shanbhogue about 12 years
    Moreover, if it did support, whats the point in even asking the question?
  • Jens Gustedt
    Jens Gustedt about 12 years
    In your third case I think the allocation is better done as I gave it in my answer. Just malloc directly, no need to cast, this only obfuscates.
  • Jens Gustedt
    Jens Gustedt about 12 years
    First of all, C99 is now 13 years old, so shame on all compiler vendors that don't implement it. And for your second, as he says, he didn't find how this works and wanted to know.
  • Akshaya Shanbhogue
    Akshaya Shanbhogue about 12 years
    FYI many people still use Borland Turbo C in educational institutes (at least where I am from) to teach, even though the newer versions implement C99 and frankly its a great tool to learn how internally data is organized etc; again, as shown in this example. Peace out.