gpt4 book ai didi

c - 如何复制 "double pointer"?

转载 作者:太空宇宙 更新时间:2023-11-04 07:56:29 26 4
gpt4 key购买 nike

我是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)被调用两次。那是因为我无法复制 topTypesbottomTypes .当我这样做时,代码产生了预期的输出。

为了避免重复调用,我没有这样做

**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

我希望这是清楚的。否则不要犹豫,说我不清楚,我会尝试做一个可重现的例子,但这并不容易。我在 SO 上发现了类似的问题,但没有一个能让我解决我的问题。

编辑

下面是一个完整的重现示例。我承认,不是非常少。

#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?
  • 你可以使用 FAM如果你不想要太多的 malloc()
  • 每次删除 topTypesbottomTypescellTypes 时都会发生内存泄漏,我想它只发生在您的 [mcve] 中。<
  • 在您的原始代码中,您使用 VLA ,这应该小心使用。
  • 您使用 unsigned 而不是 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);
}

关于c - 如何复制 "double pointer"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49753801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com