【问题标题】:How to pass a 2D array to a function in C when the array is formatted like this?当数组像这样格式化时,如何将二维数组传递给 C 中的函数?
【发布时间】:2016-02-21 01:12:39
【问题描述】:

我想创建一个数组(称为 Csend),然后创建一个稍微修改它的函数,例如为每个元素添加 0.05。我遇到的问题是数组的格式,我不确定如何正确地将它传递给函数。我在this guide 之后以这种方式分配了内存,以便以后可以将其放入 MPI_Send 和 MPI_Recv。

这是我的尝试:

#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"


int main(int argc, char **argv) {

  int N = 32;
  int dim = 3;
  float a = 10.0; // size of 3D box
  int size, rank, i, j, k, q;
  float **C, **Csend, **Crecv;
  float stepsize = 0.05;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  float **alloc_2d_float(int rows, int cols) {
    float *data = (float *)malloc(N*dim*sizeof(float));
    float **array= (float **)malloc(N*sizeof(float*));
    for(i=0; i<N; i++) {
        array[i] = &(data[dim*i]);
     }
    return array;
}

  C = alloc_2d_float(N,dim);
  Csend = alloc_2d_float(N,dim);
  Crecv = alloc_2d_float(N,dim);

if(rank == 0) {
for (i = 0; i < N; i++) {
    for (j = 0; j < dim; j++) {
        Csend[i][j] = (float)rand()/(float)(RAND_MAX/a);
  }}
}

  // FUNCTION TO MODIFY MATRIX //
  float randomsteps(float *matrix, int N, int dim) {
  int i, j;
for(i = 0; i < N; i = i+2) {
        for (j = 0; j < dim; j++) {
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize;
}
}
return matrix;
  } 

C = randomsteps(Csend, 32, 3);
  for (i=0; i<N; i++){
    for (j=0; j<dim; j++){
      printf("%f, %f\n", Csend[i][j], C[i][j]);
    }
  }

 MPI_Finalize();

  return 0;
}

我遇到的问题是像这里一样格式化,我收到错误消息,并且以没有给出错误消息的方式格式化,C 只是空的。

这是错误信息:

test.c: In function ‘randomsteps’:
test.c:46: error: incompatible types when returning type ‘float *’ but ‘float’ was expected
test.c: In function ‘main’:
test.c:49: warning: passing argument 1 of ‘randomsteps’ from incompatible pointer type
test.c:39: note: expected ‘float *’ but argument is of type ‘float **’
test.c:49: error: incompatible types when assigning to type ‘float **’ from type ‘float’

感谢您的帮助!

【问题讨论】:

  • 能发Minimal, Complete, and Verifiable example就更好了。通过查看发布的代码很难理解您的程序在做什么。
  • 嗯,有什么问题吗? (即错误消息是什么?)
  • 对不起,我已经编辑了它,所以有更多的程序。在这种情况下,错误是“返回类型'float *'但预期'float'时的类型不兼容”这似乎是一个小问题,但每次我尝试修复一件事时,它似乎都会演变成另外三个问题。
  • 错误出现在哪里?

标签: c arrays mpi


【解决方案1】:

您在矩阵的一维表示和指向它的指针方法的二维指针之间感到困惑。

*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize; -> 这行暗示matrix 只是线性集合,它像使用索引操作的矩阵一样被访问。

float **C; -> 这意味着您需要一个可以作为C[i][j] 访问的矩阵。

坚持任何一种表述。此外,由于您的函数返回一个矩阵,如果您想要一个没有索引操作访问权限的二维矩阵,则返回类型应该是 float*(如果二维矩阵被认为是线性数组操作)或 float**

float* matrix = malloc(row * cols * sizeof(float)); // This is a linear version.
// matrix[i*cols + j] gives you the (i, j)th element.

float** matrix = malloc(rows * sizeof(float*)); 
for(int i = 0; i < rows; ++i)
    matrix[i] = malloc(cols * sizeof(float));
// Now you can access matrix[i][j] as the (i, j)th element.

这是一种在两种格式之间相互转换的方法。

float* linearize(float** matrix, unsigned int rows, unsigned int cols)
{
    float* linear = malloc(rows * cols * sizeof(float));
    if(linear)
    {
        for(unsigned int i = 0; i < rows; ++i)
            for(unsigned int j = 0; j < cols; ++j)
                linear[i*cols + j] = matrix[i][j] ;
    }
    return linear ;
}


float** unlinearize(float* linear, unsigned int rows, unsigned int cols)
{
    float** matrix = malloc(rows * sizeof(float*));
    if(matrix)
    {
        for(unsigned int i = 0; i < rows; ++i)
        {
            matrix[i] = malloc(cols * sizeof(float));
            if(matrix[i])
            {
                for(unsigned int j = 0; j < cols; ++j)
                    matrix[i][j] = linear[i*cols + j] ;
            }
        }
    }
    return matrix ;
}

【讨论】:

  • 如果您仔细查看alloc_2d_float,您会发现该函数所做的是分配一个线性内存块,然后构造一个指向每行开头的指针向量。在使用 MPI 时,这是一个非常常见的习惯用法,因为它既允许使用 arr[i][j] 表示法,又可以按照 MPI 的预期保持内存连续。一维访问也可以作为*(arr[0] + i*dim + j),因为arr[0] 指向整个块的开头。在后一种情况下使用arr 只是一个菜鸟错误。
  • 谢谢!这些功能真的很有帮助。我应该能够用matrix[i][j] = matrix[i][j] + stepsize; 切换行*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize; 吗?我认为这是不对的,因为这会将这些值变为 0.05 而不是旧值 + 0.05。
  • 哦,我明白了!我只需要创建一个新矩阵,例如newmatrix[i][j] = matrix[i][j] + stepsize;。再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多