我是C语言的新手,我有一个具有这种结构的函数(这段代码是不可复制的,这是“伪代码”,但我希望它足以解释我的问题):

unsigned** myfunction(double*** A, unsigned nx, unsigned ny, unsigned nz){
    unsigned* cells[nz-1];
    unsigned totallength = 0;
    unsigned lengths[nz-1];
    unsigned** bottomTypes = function1(A, nx, ny, 0);
    for(unsigned k=0; k<nz-1; k++){
        unsigned** topTypes = function1(A, nx, ny, k+1);
        unsigned** cellTypes = function2(bottomTypes, topTypes);
        unsigned length
        unsigned** goodcells = function3(cellTypes, &length);
        cells[k] = malloc(length * sizeof(unsigned));
        for(unsigned l=0; l<length; l++){
            cells[k][l] = goodcells[0][l] + k;
        }
        lengths[k] = length;
        totallength += length;
        bottomTypes = function1(A, nx, ny, k+1); // the same as topTypes
    }
    unsigned** out = malloc(4 * sizeof(unsigned*));
    ......
    ......
    return out;
}

如您所见,在循环的末尾,我确实bottomTypes = function1(A, nx, ny, k+1);这与前面介绍的topTypes相同。因此function1(A,nx,ny,k+1)被调用两次。那是因为我无法在topTypes中复制bottomTypes。当我这样做时,代码产生了预期的输出。
我没有这样做,为了避免被人怀疑,我试着
**bottomTypes = **topTypes;


bottomTypes = malloc((nx-1) * sizeof(unsigned*));
for ( int i = 0; i < nx-1; ++i ){
    bottomTypes[i] = malloc((ny-1)*sizeof(unsigned));
    memcpy(bottomTypes[i], topTypes[i], ny-1);
}

代码会编译,但我在编译时没有得到预期的结果。
topTypes复制到bottomTypes的正确方法是什么?
我希望这是清楚的。否则不要犹豫,说我不清楚,我会尽量重复,但这并不容易。我也发现了类似的问题,但没有一个能让我解决我的问题。
编辑
下面是一个完整的复制示例。我承认,不是很简单。
#include <stdlib.h> // for malloc
#include <stdio.h>  // for printf

// function to create a "three-dimensional array" (I know this is not the correct wording)
//  from a given function
double*** fun2array(double f(unsigned,unsigned,unsigned), unsigned nx, unsigned ny, unsigned nz){
    double*** out = (double***) malloc(nx * sizeof(double**));
    for(unsigned i=0; i<nx; i++){
        out[i] = (double**) malloc(ny * sizeof(double*));
        for(unsigned j=0; j<ny; j++){
            out[i][j] = (double*) malloc(nz * sizeof(double));
            for(unsigned k=0; k<nz; k++){
                out[i][j][k] = f(i,j,k);
            }
        }
    }
    return out;
}

// a three-dimensional array
double fun(unsigned i, unsigned j, unsigned k){
    return i+j+k;
}
double*** A = fun2array(fun, 2, 3, 4);

// function to "slice" a 3d-array to a 2D-array (a "matrix")
double** toMatrix(double*** A, unsigned nx, unsigned ny, unsigned k){
    double** out = (double**) malloc(nx * sizeof(double*));
    for(unsigned i=0; i<nx; i++){
        out[i] = (double*) malloc(ny * sizeof(double));
        for(unsigned j=0; j<ny; j++){
            out[i][j] = A[i][j][k];
        }
    }
    return out;
}

// function to convert double matrix to integer matrix
unsigned** floorMatrix(double** M , unsigned nx, unsigned ny){
    unsigned** out = (unsigned**) malloc(nx * sizeof(unsigned*));
    for(unsigned i=0; i<nx; i++){
        out[i] = (unsigned*) malloc(ny * sizeof(unsigned));
        for(unsigned j=0; j<ny; j++){
            out[i][j] = (unsigned) M[i][j];
        }
    }
    return out;
}

// function to sum 2 "matrices"
unsigned** matricialSum(unsigned** M1, unsigned** M2, unsigned nx, unsigned ny){
    unsigned** out = (unsigned**) malloc(nx * sizeof(unsigned*));
    for(unsigned i=0; i<nx; i++){
        out[i] = (unsigned*) malloc(ny * sizeof(unsigned));
        for(unsigned j=0; j<ny; j++){
            out[i][j] = M1[i][j] + M2[i][j];
        }
    }
    return out;
}

unsigned myfunction(double*** A, unsigned nx, unsigned ny, unsigned nz){
    unsigned** bottomTypes = floorMatrix(toMatrix(A, nx, ny, 0), nx, ny);
    unsigned** cellTypes;
    for(unsigned k=0; k<nz-1; k++){
        unsigned** topTypes = floorMatrix(toMatrix(A, nx, ny, k+1), nx, ny);
        cellTypes = matricialSum(bottomTypes, topTypes, nx, ny);
        bottomTypes = floorMatrix(toMatrix(A, nx, ny, k+1), nx, ny); // the same as topTypes
    }
    return cellTypes[0][0];
}


int main(){
    unsigned result = myfunction(A, 2, 3, 4);
    printf("result:%u\n", result);
    return 0;
}

第二次编辑
我有一个解决方案,但肯定不是最优的:
unsigned** copyMatrix(unsigned** M, unsigned nx, unsigned ny){
    unsigned** MM = malloc(nx * sizeof(unsigned*));
    for(unsigned i=0; i<nx; i++){
        MM[i] = malloc(ny * sizeof(unsigned));
        for(unsigned j=0; j<ny; j++){
            MM[i][j] = M[i][j];
        }
    }
    return MM;
}

在示例代码中,我释放了bottomTypes,然后
unsigned** bottomTypes = copyMatrix(topTypes, nx-1, ny-1);

最佳答案

我终于明白你的问题了,你用**bottomTypes = **topTypes;代替bottomTypes = topTypes;。这只是用另一个指针替换指针。
但是,您的代码有很多潜在的问题,比如内存泄漏、使用ThreeStar、强制返回malloc等等。如果您使用C的目的是为了快速,我建议您更改数据结构。malloc()很贵,除非您想用O(1)交换矩阵的两行,否则不需要为矩阵的每一行都有一个malloc。
所以:
Do I cast the result of malloc?
如果不需要太多malloc()
你每次掉到topTypesbottomTypescellTypes时都会有内存泄漏,我想只有在你的[mcve]中。
在使用FAM的原始代码中,应该小心使用。
使用无符号而不是size_t作为索引,如果不使用非常大的矩阵,这不是什么大问题。
你的[mcve]几乎没有修复,到处都是内存泄漏:

#include <stdlib.h> // for malloc
#include <stdio.h>  // for printf

// function to create a "three-dimensional array" (I know this is not the
// correct wording)
//  from a given function
double ***fun2array(double (*f)(size_t, size_t, size_t), size_t nx, size_t ny,
                    size_t nz) {
  double ***out = malloc(nx * sizeof *out);
  for (size_t i = 0; i < nx; i++) {
    out[i] = malloc(ny * sizeof *out[i]);
    for (size_t j = 0; j < ny; j++) {
      out[i][j] = malloc(nz * sizeof *out[i][j]);
      for (size_t k = 0; k < nz; k++) {
        out[i][j][k] = f(i, j, k);
      }
    }
  }
  return out;
}

// a three-dimensional array
double fun(size_t i, size_t j, size_t k) { return i + j + k; }

// function to "slice" a 3d-array to a 2D-array (a "matrix")
double **toMatrix(double ***A, size_t nx, size_t ny, size_t k) {
  double **out = malloc(nx * sizeof *out);
  for (size_t i = 0; i < nx; i++) {
    out[i] = malloc(ny * sizeof *out[i]);
    for (size_t j = 0; j < ny; j++) {
      out[i][j] = A[i][j][k];
    }
  }
  return out;
}

// function to convert double matrix to integer matrix
unsigned **floorMatrix(double **M, size_t nx, size_t ny) {
  unsigned **out = malloc(nx * sizeof *out);
  for (size_t i = 0; i < nx; i++) {
    out[i] = malloc(ny * sizeof *out[i]);
    for (size_t j = 0; j < ny; j++) {
      out[i][j] = M[i][j];
    }
  }
  return out;
}

// function to sum 2 "matrices"
unsigned **matricialSum(unsigned **M1, unsigned **M2, size_t nx, size_t ny) {
  unsigned **out = malloc(nx * sizeof *out);
  for (size_t i = 0; i < nx; i++) {
    out[i] = malloc(ny * sizeof *out[i]);
    for (size_t j = 0; j < ny; j++) {
      out[i][j] = M1[i][j] + M2[i][j];
    }
  }
  return out;
}

unsigned myfunction(double ***A, size_t nx, size_t ny, size_t nz) {
  unsigned **bottomTypes = floorMatrix(toMatrix(A, nx, ny, 0), nx, ny);
  unsigned **cellTypes = bottomTypes;
  for (size_t k = 1; k < nz; k++) {
    unsigned **topTypes = floorMatrix(toMatrix(A, nx, ny, k), nx, ny);
    cellTypes = matricialSum(bottomTypes, topTypes, nx, ny);
    bottomTypes = topTypes;
  }
  return cellTypes[0][0];
}

int main(void) {
  double ***A = fun2array(fun, 2, 3, 4);
  unsigned result = myfunction(A, 2, 3, 4);
  printf("result:%u\n", result);
}

08-19 12:34