Thread: Declare 2D array without size, give size later

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    4

    Declare 2D array without size, give size later

    I've got an interesting problem.
    I can't determine the dimensions of the 2D array until I get the information from the if or the else if, so I would like to declare it before that so it is visible from both the if and the else if. I obviously can't create it inside the if or else if because then it would be out of scope after exiting the if else statement.
    I can declare it with float **matrix beforehand but I wish to be able to do it like
    Code:
    float *matrix[];
    to make it compatible with other functions. Is this a way to get around this problem?
    Code:
    if (strcmp(argv[i], "a") == 0)			{
    				
    				sscanf(argv[i + 1], "%d", &size);
    				float *matrix[size];
    				for (j = 0; j < size; j++)
    				{
    					matrix[j] = (float *)malloc(sizeof(float) * size);
    				}
    				fill_matrix(matrix,size,size);
    			}
    else if (strcmp(argv[i], "-d") == 0)
    			{
    				/*read matrix dimensions and components from file here
    				////////////////////////////////////////////////////
    				*/
    				float *matrix[size];
    				for (j = 0; j < size; j++)
    				{
    					matrix[j] = (float *)malloc(sizeof(float) * size);
    				}
    				fill_matrix(matrix,size,size);
    			}
    else{}

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    557
    I think the easiest way is to declare a pointer to a float and allocate the array as needed. For example:

    Code:
    // lets say m and n are provided as
    // the array dimensions, like in matrix[m][n].
    
    float *matrix;
    matrix = malloc( sizeof(float) * m * n );
    
    // you can use:
    matrix[a*n+b] = 1.0f; // same as matrix[a][b] = 1.0f;
    But, of course, you need to verify if 0 <= a < m and 0 <= b < n.

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    57
    You're making a jagged array, which is probably not what you want. Instead, try a C99 dynamic array.

    Code:
    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
      int size;
      sscanf(argv[1], "%d", &size);
    
      int matrix[size][size];
      matrix[size/2][size/2] = 1;  // Do stuff
    
      return 0;
    }
    This stores the array in contiguous memory on the stack and since the width of the rows is know, it can be indexed normally. It's stored on the stack, though. Instead, you might want to do something like this.

    Code:
    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
      int size;
      sscanf(argv[1], "%d", &size);
    
      int (*matrix)[size][size] = malloc(sizeof(int) * size * size);
      matrix[size/2][size/2] = 1;  // Do stuff
    
      return 0;
    }
    This matrix lives on the heap in contiguous memory and is very usable. However, the type is dynamic. You can't pass this to a function very easily without losing type information. It's less flexible than a normal array in that way. So you'll probably end up with just a plain old int* and address using y*size+x. You might as well wrap the pointer and size in a struct while you're at it. And then you'll probably want a set of functions to operate on these matrices.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct
    {
      int *mat;
      int size;
    } Matrix;
    
    void mat_clear(Matrix m)
    {
      for(int i = 0; i < m.size * m.size; i++)
        m.mat[i] = 0;
    }
    
    Matrix mat_create(int size)
    {
      Matrix m;
      m.size = size;
      m.mat = malloc(sizeof(int) * size * size);
      mat_clear(m);
    
      return m;
    }
    
    void mat_print(Matrix m)
    {
      for(int y = 0; y < m.size; y++)
      {
        for(int x = 0; x < m.size; x++)
          printf("%d ", m.mat[y*m.size+x]);
        printf("\n");
      }
    }
    
    int main(int argc, char *argv[])
    {
      int size;
      sscanf(argv[1], "%d", &size);
    
      Matrix m = mat_create(size);
      m.mat[(size/2)*size+(size/2)] = 1;
      mat_print(m);
    
      return 0;
    }

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    4
    That works, thanks for the help and useful information.

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    I would also say that using a struct is a better way to go

    However: Don't forget to free memory that you have malloc'd - You wouldn't want a memory leak

    i.e.
    Code:
    void mat_distroy(Matrix *m)
    {
      free (m->mat);
      m->size = 0;
    }
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Best way to declare an array size
    By pepito8 in forum C Programming
    Replies: 7
    Last Post: 01-21-2018, 02:32 PM
  2. declare functions with a variable's size
    By cable in forum C Programming
    Replies: 2
    Last Post: 02-01-2012, 03:43 PM
  3. size of array - why function gives size ONE only
    By noob123 in forum C++ Programming
    Replies: 7
    Last Post: 12-18-2009, 05:20 PM
  4. How To Declare and Dynamically Size a Global 2D Array?
    By groberts1980 in forum C Programming
    Replies: 26
    Last Post: 11-15-2006, 09:07 AM
  5. Finding Words in a array[size][size]
    By ^DJ_Link^ in forum C Programming
    Replies: 8
    Last Post: 03-08-2006, 03:51 PM

Tags for this Thread