【问题标题】:Copying a pointer of a pointer (matrix) values in C在C中复制指针(矩阵)值的指针
【发布时间】:2016-08-29 16:37:00
【问题描述】:

问题如下: 我创建了一个动态矩阵,使用指针matrix1

我想将此矩阵的副本创建到另一个,matrix2

我想这样做,这样我就可以与matrix2 混淆,而不会与matrix1 混淆 所以我尝试执行以下操作:

int main()
{
    int **matrix1, **matrix2, size1 = 10, size2 = 2;
    matrix1 = create_matrix(size1, size2);

    //I want to copy the value of matrix1 into matrixq2 and NOT the index
    **matrix2 = **matrix1
}

但是程序中断并显示以下内容:

我知道,从外观上看,将函数 create_matrix 使用两次会更容易,matrix1 和另一个 matrix2。但是在我原来的程序中,这将是太多的工作,因为我做了很多事情来完成矩阵。 哦,顺便说一句,我想避免使用 C++,有没有办法在不使用它的情况下做到这一点?对我来说会更好。

“create_matrix”代码如下:

//The program will read a file with the name of endereco, and create a matrix contPx3 out of it
int ** cria_matrix(char endereco[], int contP)
{
    FILE *fPointer;
    int i, contE, auxIndex, auxNum, **processos, cont_line = 0;
    char line[100];
    bool flag = true, flag2;

    fPointer = fopen(endereco, "r");

//Here the creation of the matrix
    processos = (int**)malloc(sizeof(int*) * contP);
    for (i = 0; i < contP; i++)
        processos[i] = malloc(sizeof(int) * 3);



//For now and on, is the rules of how the data will be placed on the matrix
    contP = 0;
    while (!feof(fPointer) && flag)
    {

        memset(&line[0], 'Ì', sizeof(line));
        fgets(line, 100 , fPointer);
//Bassicaly is that in each line there will be 3 numbers only, diveded but as many spaces you want. The numbeer will be placed on the matrix on the determined line they are.
        auxIndex = 0;
        flag2 = false;
        if(line[0] != '#')
            for (i = 0; i < 100; i++)
            {
                if (line[i] != ' ' && line[i] != '\n' && line[i] != '\0' && line[i] != 'Ì')//&&  line[i] != 'à'
                {
                    auxNum = line[i] - '0';
                    processos[contP][auxIndex] = auxNum;
                    auxIndex++;
                    flag2 = true;

                }
            }

        if (flag2)
            contP++;



        cont_line++;
        if (auxIndex != 3 && auxIndex != 0)
        {
            flag = false;
            printf("ERRO na linha: %d No processo: %d\nProvavelmente mais ou menos que 3 numeros separado por espacos\n", cont_line, contP);
        }

    }
    fclose(fPointer);
    if (!flag)
        system("PAUSE");
    return processos;
}

【问题讨论】:

  • 你没有发布完整的代码。
  • @parik,这不是一个有效的副本。那里的数据类型是T[N][M],而这里是T**。从那里盲目地应用解决方案可能会使 OPs 程序崩溃。
  • 另外,复制第一级间接,而不是第一个元素:memcpy(*matrix2, *matrix1, size1 * size2 * sizeof(int))。如果你定义正确,**matrix1 应该是int
  • 最后还是需要分配实际的matrix2。目前,它指向垃圾箱。

标签: c matrix pointer-to-pointer cop


【解决方案1】:

matrix1 指向行指针数组,*matrix1 是指向保存第一行实际数据的数组的指针,**matrix1 是第一行第一个元素的值。 matrix1 及其每个元素都是动态分配的数组。

matrix2 是您显示的代码中的未初始化(垃圾)指针。它既没有分配行指针也没有分配数据缓冲区。

要达到你想要的结果,你需要先分配matrix2的元素,然后只复制matrix1的数据部分。

int **copy_matrix(int **mat, int size1, int size1)
{
    int row;

    int **res = malloc(size1 * sizeof(int *));
    for(row = 0; row < size1; row++) {
        res[row] = malloc(size2 * sizeof(int));
        memcpy(res[row], mat[row], size2 * sizeof(int));
    }
    return res;
}

...

matrix2 = copy_matrix(matrix1, size1, size2);

另一种方法是为副本分配一个缓冲区。虽然这可能是一般存储矩阵的更好方法,但它可能对您没有那么有用,因为您将无法像为matrix1 那样释放matrix2 的内存:

int **copy_matrix(int **mat, int size1, int size2)
{
    int row;
    int **res = malloc(size1 * sizeof(int *));
    res[0] = malloc(size1 * size2 * sizeof(int));

    for(row = 0; row < size1; row++) {
        res[row] = res[0] + row * size2;
        memcpy(res[row], mat[row], size2 * sizeof(int));
    }
    return res;
}

【讨论】:

  • 我相信 **matrix1 是第一个元素的值,而不是它的地址。
  • 接下来,我相信你的 memcpy 假设有 size1 * size2 int 值存储在内存位置 *matrix1。我认为情况并非如此。我认为那里只存储了 size2 int 值。我认为 memcpy 读取越界。你同意吗?
  • 除非 OP 发布 create_matrix 函数,否则我将采用整体数据数组假设。
  • create_matrix 函数将创建矩阵并在其上放置值。是的,矩阵是size1xsize2
  • @Hirosam。您的代码模棱两可。请在您的问题中发布函数的实际代码。
【解决方案2】:

这个怎么样-

matrix2 = (int**)malloc(sizeof(int*)*size1);
for(int idx = 0; idx < size1; ++idx) {
    matrix2[idx] = (int*)malloc(sizeof(int)*size2);
    for(int idx2 = 0; idx2 < size2; ++idx2) {
        matrix2[idx][idx2] = matrix1[idx][idx2];
    }
}

【讨论】:

  • 在 OP 发布完整代码之前很长时间直觉地认为缓冲区不是单片的。
【解决方案3】:

您需要了解复制指针、浅拷贝和深拷贝之间的区别。 考虑一下这个

struct employee
{
   char *name;
   float salary;
   int payrollid;
}

现在有三种复制员工的方法

struct employee * emp1;  // points to an employee, set up somehow
struct employee * emp2;  // empty pointer, null or whatever

emp2 = emp1;  // copy pointers. emp1 and emp2 now point to the same object.

指针复制

struct employee  employee1;  // employee, set up
struct employee  employee2;  // uninitalised emplyee

memcpy(&employee2, &employee1, sizeof(struct employee)); // shallow copy

浅拷贝

struct employee * emp1;  // points to an employee, set up somehow
struct employee * emp2;  // empty pointer, null or whatever

emp2 = copyemployee(emp1);

struct employee *copyemployee(struct employee *e)
{
   struct employee *answer = malloc(sizeof(struct employee));
   if(!answer)
     goto error_exit;
   answer->name = malloc(strlen(e->name) + 1);
   if(!answer->name)
      goto error_exit;
   strcpy(answer>name, e->name);
   answer->salary = e->salary;
   answer->payroolid = e->payrollid;
   return answer;
error_exit:
   /* out of memory handle somehow, usually by returning null
}

深拷贝

如您所见,即使对于只有一个可变长度字段的简单结构,进行深拷贝也是一项相当大的工作。 都有它们的用途,尽管浅拷贝可能是三者中最没用且最容易出错的。

你可能只需要分配一个指针。

【讨论】:

  • 因此,您在谈论结构时开始切线,OP 不使用该结构,然后承认您确实不知道这与 OP 的问题有什么关系。另外,你的最终答案是错误的。
  • 指针拷贝是什么我能理解,但是浅拷贝和深拷贝让我很困惑。
  • @Hirosam。这是一个与 Java 等语言更相关的概念,其中指针是隐式的而不是显式的。深拷贝意味着您复制指向行的指针和行的内容,而浅拷贝意味着您只复制指向行的指针,但您的数据缓冲区是相同的(与您想要的相反)。
猜你喜欢
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多