title: Send and receive dynamic arrays in MPI
body: <p>I have a big problem with send and (or) receiving dynamic arrays with MPI. Below is just a part of my code, but it should be enough to see what i am doing wrong. Please help me, i'm after all night of searching solution. 
  I get sth like this:
  <strong>* glibc detected <em></strong> ./mv2.out: munmap_chunk(): invalid pointer: 0x0000000000da2a70 <strong></em> <em></strong> glibc detected <strong></em> ./mv2.out: malloc(): memory corruption (fast): 0x0000000000da2a50 *</strong></p>
  
  <p>When I replace dynamic arrays with static everything works perfect.</p>
  
  <pre><code>#include "mpi.h"
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define MASTER 0
  #define FROM_MASTER 1
  #define FROM_WORKER 2
  
  double **alloc_2d_array(int rows, int cols) {
      int i;
      double *data = (double *)malloc(rows*cols*sizeof(double));
      double **array= (double **)malloc(rows*sizeof(double*));
      for (i=0; i&lt;rows; i++)
          array[i] = &amp;(data[cols*i]);
  
      return array;
  }
  
  int main (int argc, char *argv[])
  {
      int degree,
      numtasks,
      taskid,
      numworkers,
      source,
      dest,
      mtype,
      rows,
      offset,
      averow,
      extra,
      i, j, k, rc;
  
      MPI_Status status;
  
      double **a, *b, *c;
  
      MPI_Init(&amp;argc,&amp;argv);
      MPI_Comm_rank(MPI_COMM_WORLD,&amp;taskid);
      MPI_Comm_size(MPI_COMM_WORLD,&amp;numtasks);
      if (numtasks &lt; 2 )
      {
          printf("Aby rozpoczac obliczenia rownolegle potrzeba co najmniej 2 procesow.\n");
          MPI_Abort(MPI_COMM_WORLD, rc);
          exit(1);
      }
      numworkers = numtasks-1; 
  
      if (taskid == MASTER)
      {
          printf("Podaj stopien macierzy: \n");
          scanf ("%d", &amp;degree);
          printf("Obecnie dostepnych jest %d procesow do dyspozycji mastera.\n", numtasks);
  
          FILE *file;
  
          file = fopen("matrix.txt", "r");
          if(file == NULL)
          {
              printf("Nie mozna otworzyc pliku!\n");
              MPI_Finalize();
              exit(0);
          }
  
          a = alloc_2d_array(degree, degree);
          b = (double*) malloc(sizeof(double) * degree);
          c = (double*) malloc(sizeof(double) * degree);
  
          printf("Tworzenie macierzy z pliku\n");
          for(i = 0; i &lt; degree; i++)
              for(j = 0; j &lt; degree; j++)
                  fscanf(file, "%lf", &amp;a[i][j]);
  
          for(i = 0; i &lt; degree; i++)
          {
              for(j = 0; j &lt; degree; j++)
              {
                  printf("%f", a[i][j]);
              }
              printf("\n");
          }
  
          printf("Tworzenie wektora z pliku\n");
          for(i = 0; i &lt; degree; i++)
              fscanf(file, "%lf", &amp;b[i]);
  
          for(i = 0; i &lt; degree; i++)
          {
              printf("%f\n", b[i]);
          }
  
          fclose(file);
  
          averow = degree / numworkers;
          extra = degree % numworkers;
          offset = 0;
          mtype = FROM_MASTER;
          for (dest = 1; dest &lt;= numworkers; dest++)
          {
              rows = (dest &lt;= extra) ? (averow + 1) : averow;
              printf("Wysylanie %d wierszy do procesu nr %d, z offset'em = %d\n", rows, dest, offset);
              MPI_Send(&amp;degree, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
              MPI_Send(&amp;offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
              MPI_Send(&amp;rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
              MPI_Send(&amp;a[offset][0], rows * degree, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
              MPI_Send(&amp;b, degree, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
              offset = offset + rows;
          }
  
          mtype = FROM_WORKER;
          for (i=1; i&lt;=numworkers; i++)
          {
              source = i;
              MPI_Recv(&amp;offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &amp;status);
              MPI_Recv(&amp;rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &amp;status);
              MPI_Recv(&amp;c[offset], rows, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &amp;status);
              printf("Otrzymalem wyniki od procesu nr %d\n", source);
          }
  
          printf("***\n");
          printf("Wektor wynikowy:\n");
          for (i = 0; i &lt; degree; i++)
          {
              printf("\n%6.2f", c[i]);
          }
          printf("\n***\n");
          printf ("KONIEC\n");
      }
  
  
      if (taskid &gt; MASTER)
      {
          b = (double*) malloc(sizeof(double) * degree);
          c = (double*) malloc(sizeof(double) * degree);
  
          mtype = FROM_MASTER;
          MPI_Recv(&amp;degree, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;a, rows * degree, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &amp;status); //HERE IS THE PROBLEM
          MPI_Recv(&amp;b, degree, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
  
          for (i = 0; i &lt; rows; i++)
          {
              c[i] = 0.0;
              for (j = 0; j &lt; degree; j++)
                  c[i] += a[i][j] * b[j];
          }
          mtype = FROM_WORKER;
          MPI_Send(&amp;offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;c, rows, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
      }
  
      MPI_Finalize();
  }
  </code></pre>
  
  <p>The shortest version to reproduce error:</p>
  
  <pre><code>#include "mpi.h"
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define MASTER 0
  #define FROM_MASTER 1
  #define FROM_WORKER 2
  
  double **alloc_2d_array(int rows, int cols) {
      int i;
      double *data = (double *)malloc(rows*cols*sizeof(double));
      double **array= (double **)malloc(rows*sizeof(double*));
      for (i=0; i&lt;rows; i++)
          array[i] = &amp;(data[cols*i]);
  
      return array;
  }
  
  int main (int argc, char *argv[])
  {
      int degree,
      taskid,
      source,
      dest,
      mtype,
      rows,
      offset,
      i, j;
  
      MPI_Status status;
  
      double **a, *b, *c;
  
      MPI_Init(&amp;argc,&amp;argv);
      MPI_Comm_rank(MPI_COMM_WORLD,&amp;taskid);
      MPI_Comm_size(MPI_COMM_WORLD,&amp;numtasks);
  
      if (taskid == MASTER)
      {
          FILE *file;
  
          file = fopen("matrix.txt", "r");
  
          a = alloc_2d_array(degree, degree);
          b = (double*) malloc(sizeof(double) * degree);
          c = (double*) malloc(sizeof(double) * degree);
  
          for(i = 0; i &lt; degree; i++)
              for(j = 0; j &lt; degree; j++)
                  fscanf(file, "%lf", &amp;a[i][j]);      
  
          for(i = 0; i &lt; degree; i++)
              fscanf(file, "%lf", &amp;b[i]);
  
          fclose(file);
  
          offset = 0;
          mtype = FROM_MASTER;
          MPI_Send(&amp;degree, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;a[offset][0], rows * degree, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
          MPI_Send(&amp;b, degree, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
          }
      }
  
  
      if (taskid &gt; MASTER)
      {
          a = alloc_2d_array(degree, degree);
          b = (double*) malloc(sizeof(double) * degree);
          c = (double*) malloc(sizeof(double) * degree);
  
          mtype = FROM_MASTER;
          MPI_Recv(&amp;degree, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          // v HERE IS THE PROBLEM v
          MPI_Recv(&amp;a, rows * degree, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
          MPI_Recv(&amp;b, degree, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &amp;status);
      }
  
      MPI_Finalize();
  }
  </code></pre>
  
  <p>EDIT: Version without sending from worker to master works correctly, but when I add responsing application suspends.
  In the link below you can find example with static arrays. When I replace them with dynamic ones, application doesn't work properly.
  <a href="https://computing.llnl.gov/tutorials/mpi/samples/C/mpi_mm.c" rel="nofollow">https://computing.llnl.gov/tutorials/mpi/samples/C/mpi_mm.c</a></p>