3

I'm making a randomized n*n matrix, but I do not know the value of n until the program is already running.

I'm capable of creating the n*n matrices in main() like so:

    double (*m1)[n];
    m1 = malloc(sizeof *m1 * n);

    double (*m2)[n];
    m2 = malloc(sizeof *m2 * n);

But now I must use these matrices outside of main and need them to be global, but I'm completely clueless how to make them global. I intend to read these two matrices with multiple threads and need them easily accessible. I know I can make a struct to pass multiple parameters, but I would need to define a struct with variable length arrays globally so the problem rearises. Thank you for your time.

  • 3
    How about just a plain standard [variable-length array](https://en.wikipedia.org/wiki/Variable-length_array)? Like `double m1[n][n];`? And if other functions need to use the matrices, *pass them as arguments*? – Some programmer dude Oct 11 '17 at 05:39
  • 1
    try to follow this link it may be u will get some clue[https://stackoverflow.com/questions/7839637/save-2d-dynamic-array-matrix-for-global-access-c] – Mohammad Adil Oct 11 '17 at 05:46
  • @Someprogrammerdude Afterwards I'll be reading the arrays with multiple threads. As far as I know I can't pass a struct with variable length arrays to threads. Thus, the problem of wanting them global. – Daniel Hogan Oct 11 '17 at 05:50
  • The correct solution is to not do spaghetti programming with global variables. – Lundin Oct 11 '17 at 06:52

2 Answers2

3

Just declare as double pointer and allocate memory in main. For more details refer this

#include <stdio.h>
int **a;
void fun(int n)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            printf("%d ",a[i][j]);
    }
}
int main(void) 
{
    int n;
    scanf("%d",&n);
    a = (int **)malloc(n * sizeof(int *));
    for(int i=0;i<5;i++)
    {
        a[i]=(int*)malloc(n*sizeof(int));
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    fun(n);
    return 0;
}

Working Code : https://ideone.com/OMQ4qA

SRIDHARAN
  • 1,196
  • 1
  • 15
  • 35
  • This is great! One last question, how would I properly free the allocated memory? Simply free(a), in this case? – Daniel Hogan Oct 11 '17 at 06:02
  • No. you can't do that. Refer https://stackoverflow.com/questions/11015360/free-a-double-pointer" – SRIDHARAN Oct 11 '17 at 06:03
  • 1
    This is not a 2D array though, but a pointer-based lookup table. Cache access will be slow and this will cause heap fragmentation, needlessly. Unless the OP needs to change "array" dimensions individually, there is absolutely no reason to use this code. Why have slow access when you can have fast access? See [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). (But of course VLA is not an option either, when you do spaghetti programming with global variables.) – Lundin Oct 11 '17 at 07:09
  • I have few doubts what is OP(output I guess) and VLA? ( I am trying to learn new things) – SRIDHARAN Oct 11 '17 at 10:20
  • @Sridharan OP = internet slang for original poster, the person asking the question. VLA is a C programming term for variable-length arrays. – Lundin Oct 11 '17 at 11:54
3

The correct, proper solution is to not use globals. Allocate the array in the thread which will persist throughout the execution of the whole program.

If that, for reasons unknown, is not an option, then you will have to come up with some solution that stores the array size globally too. You could create a simple ADT for this, such as a struct with a "mangled" 2D array in the form of a flexible array member. Example:

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
  size_t x;
  size_t y;
  double array [];
} double_array2d_t;

double_array2d_t* array2d = NULL;

int main()
{
  /* let x and y be some manner of run-time values: */
  int x = 3;
  int y = 2;

  array2d = malloc(sizeof(*array2d) + sizeof(double[x][y]));
  array2d->x = x;
  array2d->y = y;

  double count = 0.0;
  for(int i=0; i<x; i++)
  {
    for(int j=0; j<y; j++)
    {
      array2d->array[i*y + j] = count++;
      printf("%f ", array2d->array[i*y + j]);
    }
    printf("\n");
  }

  ...

  free(array2d);
}

And of course if you access this from multiple threads, you have to protect the data with a mutex as always.

Lundin
  • 195,001
  • 40
  • 254
  • 396