# Thread: filling 2D array with the help of 1D array

1. ## filling 2D array with the help of 1D array

Hi,

(I am using vector() and matrix() functions from "Numerical recipes in C".)

There are 100 numbers to be stored in 2D array of 10 rows and 10 columns.
100 numbers are stored in a 1D array.

I get "segmentation fault" at the line indicated in the segment of my code below:

Code:
```  :
:
#define size 100
#define nl 1
#define nh 10

:
:
float  **sensor_matrix,  *shift;
shift=vector(1,size);
sensor_matrix=matrix(nl,nh,nl,nh);
:
:

k=1;
for(i=nl;i<=nh;i++)
{

for(j=nl;j<=nh;j++)
{
sensor_matrix[i][j]=shift[k];               // I get segmentation fault here

k++;
}
}
:
:
free_matrix(sensor_matrix,nl,nh,nl,nh);
free_vector(shift,1,size);```

Any help will be appreciated.

Thanks and Regards
iamc

2. Code:
```    shift=vector(1,size);
sensor_matrix=matrix(nl,nh,nl,nh);```
How is vector and matrix defined???

3. How is vector and matrix defined???
These can be found in "Numerical Recipes in C".

This is matrix( ):

Code:
```float **matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;

/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;

/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;

for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;

/* return pointer to array of pointers to rows */
return m;
}```
This is vector ( ):

Code:
```float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;

v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}```

4. I've no problem running your program. The problem will probably be somewhere else.

5. Ehh.. why are you returning v-n1+NR_END instead of just v when creating a vector?

6. I was trying to wrap my mind around the code, and I can't quite understand this bit:
Code:
```m += NR_END;
m -= nrl;

AND

m[nrl] += NR_END;
m[nrl] -= ncl;```
Could someone explain it to me?

Furthermore, to the best of my understanding, a matrix is an 2D array of dimensions n * m, why does the matrix() takes 4 arguments? If someone asked me for a matrix creating function, I'd give them the following and call it a job well done.
Code:
```float** newMatrix(int n, int m) {
float** mtx = malloc( sizeof(*mtx) * n);
for (int i = 0; i < n; i++) {
mtx[i] = malloc( sizeof(**mtx) * m);
}

return mtx;
}```
I feel like either I'm missing something important or the code attempts some sort of shenanigans.

7. Can you post the complete code that causes segfault?

8. Can you post the complete code that causes segfault?
I REPEAT: I AM USING "NUMERICAL RECIPES IN C" FUNCTIONS.
THESE FUNCTIONS ARE MEANT FOR UNIT-OFFSET. i.e.
INSTEAD OF STARTING THE INDEX OF 1D ARRAY FROM [0] ( OR FOR 2D [0][0]), THEY WILL START INDEX FROM [1] FOR 1D ARRAY AND FROM [1][1] FOR 2 D ARRAY.
vector( ) corresponds to 1D
matrix( ) corresponds to 2D

I do not know what is happening inside these two functions; I have never tried that.
Many times these routines (from Numerical Recipes) are used considering them as black boxes.

This is my whole code (nrutil.c contains 2 functions mentioned above):

Code:
```#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include"nrutil.c"

#define size 100
#define nl 1
#define nh 10

float ran1(long *idum);                 // this is random number generator from Numerical Recipe

int main()
{
long *idum;
int i,k,r;
long j;
float n1,n2,n3;

float *dx, *dy, *shift,**sensor_matrix;
shift=vector(1,size);
dx=vector(nl,nh);
dy=vector(nl,nh);
sensor_matrix=matrix(nl,nh,nl,nh);

//________________ dx _________________________
j=-5;
idum = &j;
for(i=1;i<=size;i++)
{
n1=ran1(idum);
n2=n1-0.5;
n3=n2*10.0;

dx[i]=n3;
}

//__________________ dy ________________________

j=-9;
idum = &j;
for(i=1;i<=size;i++)
{
n1=ran1(idum);
n2=n1-0.5;
n3=n2*10.0;

dy[i]=n3;
}

//___________________ shift _____________________

for(i=1;i<=size;i++)
{
shift[i]=sqrtf( powf(dx[i],2.0) + powf(dy[i],2.0) );

}

//___________________ Sensor Matrix ______________

k=1;
for(i=nl;i<=nh;i++)
{

for(r=nl;r<=nh;r++)
{

sensor_matrix[i][r]=shift[k];        // I get seg. fault here

k++;
}
}
//_________________________________________________

free_matrix(sensor_matrix,nl,nh,nl,nh);
free_vector(dx,nl,nh);
free_vector(dy,nl,nh);
free_vector(shift,1,size);

return 0;

}```

Regards,
iamc

9. I finally know why!!!

Code:
``` dx=vector(nl,nh);
dy=vector(nl,nh);

for(i=1;i<=size;i++)
{
n1=ran1(idum);
n2=n1-0.5;
n3=n2*10.0;

dx[i]=n3;        /* size is 100 and see how you allocated! same for dy!
heap corruption! undefined behaviour!
*/
}```

10. Originally Posted by msh
I feel like either I'm missing something important or the code attempts some sort of shenanigans.
Did you read the one line of comment on the function itself that you yourself posted?

11. Originally Posted by tabstop
Did you read the one line of comment on the function itself that you yourself posted?
Yes. As I understood it, an 2D array whose elements can be addressed by a arbitrary indexing scheme is created. I.e. if nrl was 13, that would be the index for the first row, and if nch was 90, that would be the index for the last column of the row. Like that?

12. Originally Posted by msh
Yes. As I understood it, an 2D array whose elements can be addressed by a arbitrary indexing scheme is created. I.e. if nrl was 13, that would be the index for the first row, and if nch was 90, that would be the index for the last column of the row. Like that?
Right. So you can specify that it should start with a[4][7] and finish with a[11][15]. That's why there are four numbers given in, because you need two starts and two ends.

And, apologies: it looks like you didn't post the code after all. I'll keep posters straight one day, but it looks like today is not that day.

13. Originally Posted by tabstop
Right. So you can specify that it should start with a[4][7] and finish with a[11][15]. That's why there are four numbers given in, because you need two starts and two ends.

And, apologies: it looks like you didn't post the code after all. I'll keep posters straight one day, but it looks like today is not that day.
(Apology accepted. )

Okay. So why would someone do something like this? What's the reasoning behind it?

14. Originally Posted by msh
(Apology accepted. )

Okay. So why would someone do something like this? What's the reasoning behind it?
Sometimes people are unable or unwilling to start at 0 and want to start at 1 instead (either for compatibility with other languages, or for compatibility with the written version of the algorithm) (although I'm not sure that the memory allocated here is compatible with other languages, I'd have to check). Sometimes there are natural reasons why you want your indices to go from 50 to 150 (say you're doing a count/histogram, and that's the range of the values you are counting).

15. Originally Posted by tabstop
Sometimes people are unable or unwilling to start at 0 and want to start at 1 instead (either for compatibility with other languages, or for compatibility with the written version of the algorithm) (although I'm not sure that the memory allocated here is compatible with other languages, I'd have to check). Sometimes there are natural reasons why you want your indices to go from 50 to 150 (say you're doing a count/histogram, and that's the range of the values you are counting).
Thanks for the explanation!