Click to See Complete Forum and Search --> : Memcopying data of pointer to a pointer


WeeBeng
December 17th, 2002, 11:44 PM
This is more of a C type of question.I need to copy the memory of a 2-dimensional array into another target buffer. Usually this is what I do if the 2-dimensional array is small.

double testmatrix1[Numtimepts][Numtimepts];
int I,J;

for(I=0;I<Numtimepts;I++){
for(J=0;J<Numtimepts;J++){
testmatrix1[I][J]=(double)rand()/RAND_MAX*2.1;
}
}
memcpy((void *)mxGetPr(mat1), (void *)testmatrix1, sizeof(testmatrix1));

where mxGetPr(mat1) is a function of an external programme (Matlab) I am linking this C programme to and gives a pointer to the memory buffer I need.

However for an unknown 2-dimensional array, I usually use pointer to a pointer .

double **matrix1;

for(I=0;I<Numtimepts;I++)
matrix1 = malloc(Numtimepts*sizeof(double *));

for(I=0;I<Numtimepts;I++)
matrix1[I]=malloc(Numtimepts*sizeof(double *));

for(I=0;I<Numtimepts;I++){
for(J=0;J<Numtimepts;J++){
matrix1[I][J]=(double)rand()/RAND_MAX*2.1;
}
}
memcpy((void *)mxGetPr(mat1), (void *)matrix1[0], Numtimepts*Numtimepts*sizeof(double));



I tried the above statement but it failed to copy the correct memory buffer.

This statement:

memcpy((void *)mxGetPr(mat1), (void *)matrix1[0], Numtimepts*sizeof(double));

just allows me to copy the first row of the matrix1 which is understandable. So how do I copy the rest of the rows of the matrix1 into the target memory row by row?

The following statement

for (I=0;I<Numtimepts;I++)
memcpy((void *)mxGetPr(mat1), (void *)(matrix1[I]+Numtimepts*I*sizeof(double)), Numtimepts*sizeof(double));


also fails to acheive what I want.

Finally, due to the way Matlab declares its arrays, ie column by column instead of row by row like C, I will end up with a transpose matrix, is there any way to copy my memory column by column to the memory buffer?

I understand that Cpp may deal with the problem more efficiently but as I am still catching up on Cpp , this current solution will serve my needs for the time being.

Thanx a lot for any help.

DanM
December 18th, 2002, 12:43 AM
for (I=0;I<Numtimepts;I++)
memcpy((void *)mxGetPr(mat1), (void *)(matrix1[I]+Numtimepts*I*sizeof(double)), Numtimepts*sizeof(double));

should be replaced with

for (I=0;I<Numtimepts;I++)
memcpy((void *)((double*)mxGetPr(mat1) + i * Numtimepts), (void *)(matrix1[I]+Numtimepts*I*sizeof(double)), Numtimepts*sizeof(double));

Otherwise it will copy each row to the mem area pointed by mxGetPr(mat1) and you will end up with the first Numtimepts*sizeof(double)) bytes containing the last row and the remaining bytes being uninitialized.

Dan

WeeBeng
December 18th, 2002, 07:36 PM
Thanx for the help, I managed to resolve the problem with a little modification to the suggested code. However I seem to be having problems with the free function. I can compile and link the code but it cannot run. Any suggestions as to what is wrong and how to correct it? How can I also increase my stack size for my programme if I am compiling using MSVC 6.0?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "engine.h"

enum{
Numtimepts=5
};
Engine *ep;
mxArray*mat1=NULL;
int I,J;
double **matrix1,**matrix2;


srand(time(NULL));


matrix1 = malloc(Numtimepts*sizeof(double *));
matrix2=malloc(Numtimepts*sizeof(double *));

for(I=0;I<Numtimepts;I++){
matrix1[I]=malloc(Numtimepts*sizeof(double *));
matrix2[I]=malloc(2*sizeof(double *));
}

for(I=0;I<Numtimepts;I++){
for(J=0;J<Numtimepts;J++){
matrix1[I][J]=(double)rand()/RAND_MAX*2.1;
}
matrix2[I][0]=(double)rand()/RAND_MAX*1.15;
matrix2[I][1]=(double)rand()/RAND_MAX*0.15;
for (I=0;I<Numtimepts;I++)
memcpy((void *)((double*)mxGetPr(mat1) +I* Numtimepts), (void *)(matrix1[I]), Numtimepts*sizeof(double));


/*Problem comes with this part of the code, when I run the programme with this part of the code added, the programme always crashes but runs ok when this part is omitted.*/
for (I=0;I<Numtimepts;I++)
free(matrix1[I]);
free(matrix1);

I am running this on a PIV 1.5 with 256MB ram.

DanM
December 18th, 2002, 08:30 PM
matrix1[I]=malloc(Numtimepts*sizeof(double *));
matrix2[I]=malloc(2*sizeof(double *));

should be replaced with:

matrix1[I]=malloc(Numtimepts*sizeof(double));
matrix2[I]=malloc(2*sizeof(double));

You have to allocate double not double pointers.

Dan