Reputation: 13
The problem is the following:
I created a dynamic matrix, using pointer to pointer matrix1
I want to create a copy of this matrix into another, matrix2
I want to do that so I can mess with matrix2
without messing with matrix1
So I tried to do the following:
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
}
However the program breaks and show the following:
I understand that by the way it look, it would be easier to use the function create_matrix
two times, for matrix1
and another for matrix2
. But in the way that my original program is that would be too much work, since I do a lot of stuff to have the matrix done.
Oh, and by the way, I want to avoid using C++, is there is a way to do it without using it? It would be better for me.
the code 'create_matrix' is the following:
//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;
}
Upvotes: 1
Views: 1318
Reputation: 114330
matrix1
points to the array of row pointers, *matrix1
is a pointer to an array holding the first row of actual data, and **matrix1
is the value of first element of the first row. matrix1
and each of its elements are all dynamically allocated arrays.
matrix2
is an uninitialized (trash) pointer in the code you have displayed. It has neither the row pointer nor data buffers allocated.
To achieve your desired result, you need to first allocate the elements of matrix2
, then copy just the data portion of matrix1
over.
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);
An alternative would be to allocate a single buffer for the copy. While this is possibly a better way of storing matrices in general, it may not be as useful to you because you will not be able to free the memory of matrix2
the same way that you do for matrix1
:
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;
}
Upvotes: 1
Reputation: 6404
You need to understand the difference between copying pointers, taking shallow copies, and taking deep copies. Consider this
struct employee
{
char *name;
float salary;
int payrollid;
}
There are now three ways of copying an employee
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.
Pointer copy
struct employee employee1; // employee, set up
struct employee employee2; // uninitalised emplyee
memcpy(&employee2, &employee1, sizeof(struct employee)); // shallow copy
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
}
Deep copy
As you can see, even for a simple structure with only one variable-length field, taking a deep copy is quite a bit of work. All have their uses, though shallow copies are probably the least useful and most bug prone of the three.
You simply need to assign to a pointer, probably.
Upvotes: -1
Reputation: 486
How bout this-
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];
}
}
Upvotes: 1