在 C 中复制指针(矩阵)值的指针
Copying a pointer of a pointer (matrix) values in C
问题如下:
我创建了一个动态矩阵,使用指向指针 matrix1
的指针
我想将这个矩阵复制到另一个矩阵中,matrix2
我想这样做,这样我就可以在不干扰 matrix1
的情况下干扰 matrix2
所以我尝试执行以下操作:
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] != '[=11=]' && 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;
}
这个怎么样-
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];
}
}
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;
}
您需要了解复制指针、浅拷贝和深拷贝之间的区别。
考虑这个
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
}
深拷贝
如您所见,即使对于只有一个可变长度字段的简单结构,进行深拷贝也是一项相当大的工作。
都有它们的用途,尽管浅拷贝可能是这三种中最没有用且最容易出错的。
您可能只需要分配给一个指针。
问题如下:
我创建了一个动态矩阵,使用指向指针 matrix1
我想将这个矩阵复制到另一个矩阵中,matrix2
我想这样做,这样我就可以在不干扰 matrix1
的情况下干扰 matrix2
所以我尝试执行以下操作:
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] != '[=11=]' && 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;
}
这个怎么样-
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];
}
}
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;
}
您需要了解复制指针、浅拷贝和深拷贝之间的区别。 考虑这个
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
}
深拷贝
如您所见,即使对于只有一个可变长度字段的简单结构,进行深拷贝也是一项相当大的工作。 都有它们的用途,尽管浅拷贝可能是这三种中最没有用且最容易出错的。
您可能只需要分配给一个指针。