Reputation: 379
I am writing a C program to transpose a matrix and to test it I have a structure which contains a pointer to a set of pointers , to which I am allocating memory using malloc in a separate function. Now, my question is: can i initialize the matrix in the following format?:
cases[0].matq={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
cases[0].matq={1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16}; //or like this
where cases is an array of type struct.
Upvotes: 0
Views: 187
Reputation: 46445
Instead of having a pointer to a set of pointers for which you explicitly allocate memory, why not do the following: store the 2D array in the conventional way, then have the pointers in your structure point to it. I have made a mini complete (compiles, runs) program to show how this can work (note - this was edited after comments from @ryyker):
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int A[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; // conventional initialization
int **pp; // this is really an element of your structure
pp = malloc(4 * sizeof (int *)); // four pointers to int
int ii, jj;
for(ii=0; ii<4; ii++) pp[ii] = &A[ii][0]; // point to the original matrix
// show that it works:
for(ii=0; ii<4; ii++) {
for(jj=0; jj<4; jj++) {
printf("%d ", pp[ii][jj]);
}
printf("\n");
}
}
This gives the output you would expect:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
As you can see, with this code the array is initialized in the "normal" way, and you can address elements in this array by double dereferencing. No copies are made - all you need is the array of pointers.
It is not completely clear to me why you are doing what you are doing; so it may be that this approach doesn't work for you - but in that case I am sure you will let me know in the comments and we can tweak it.
further update
Based on various comments, perhaps this is a good way to think about your problem:
// all the test cases in a 3D array:
int testCases[5][4][4]={ \
{{1,2,3,4},{2,3,4,5},{3,4,5,6},{4,5,6,7}}, \
{{2,3,4,5},{3,4,5,6},{4,5,6,7},{1,2,3,4}}, \
{{3,4,5,6},{4,5,6,7},{1,2,3,4},{2,3,4,5}}, \
{{4,5,6,7},{1,2,3,4},{2,3,4,5},{3,4,5,6}}};
int **pp; // this is really an element of your structure
pp = malloc(4 * sizeof (int *)); // four pointers to int
// only allocate once
int ii, jj; // usual counters
int **qq; // place for the result
// create space: now we need two calls to malloc to get both the pointers, and the space
qq = malloc(4 * sizeof(int*));
qq[0]=malloc(4*4*sizeof(int)); // total block is 16 int long
for(ii=1;ii<4;ii++) qq[ii] = qq[0] + ii * 4 * sizeof(int); // set up other pointers
int tc;
for(tc = 0; tc < 5; tc++) { // loop over the test cases
// make pp point to a test case
for(ii=0; ii<4; ii++) pp[ii] = &testCases[tc][ii][0];
doTranspose(pp, qq); // assuming that the result of transposing pp is in qq
printMatrix(qq); // some code that prints the result
}
And your doTranspose
might look like:
void doTranspose(int **pp, int **qq) {
int ii, jj;
for(ii=0; ii<4; ii++) {
for(jj=0; jj<4; jj++) {
qq[ii][jj] = pp[jj][ii];
}
}
}
Copying the result into a different matrix makes the code a little easier. If you want to do an in-place transpose, you could do
void inplaceTranspose(int **pp) {
int ii, jj, temp;
for(ii=0; ii<4; ii++) {
for(jj=0; jj<4; jj++) {
temp = pp[ii][jj];
pp[ii][jj]=pp[jj][ii];
pp[jj][ii]=temp;
}
}
}
void printMatrix(int **pp){
int ii, jj;
for(ii=0; ii<4; ii++) {
for(jj=0; jj<4; jj++) {
printf("%4d ", pp[ii][jj]);
}
printf("\n");
}
}
Upvotes: 1
Reputation: 23236
Regarding can i initialize the matrix in the following format?:
cases[0].matq={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
//(even if cases[0].matq happened to be `int **`, which is not defined in your question)
No. It is not legal to do that:
OR this:
int **b={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
However, it is legal to do this:
int b[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
Regarding to which I am allocating memory using malloc in a separate function:
Since you are creating memory for the 2 dimensional array using calloc()
, your array elements would already be initialized to 0. To make further assignments use a loop, or sequential statements to assign values to each member individually.
Given you have initialized the array using malloc()
successfully, you could assign pseudo random numbers to the array in a fashion such as this:
example:
//...
srand(clock());
for(i=0;i<r;i++)
for(j=0;j<c;j++)
b[r][c]=rand();
//...
Upvotes: 0