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

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    7

    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. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Code:
        shift=vector(1,size);
      sensor_matrix=matrix(nl,nh,nl,nh);
    How is vector and matrix defined???

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    7
    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. #4
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    I've no problem running your program. The problem will probably be somewhere else.

  5. #5
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Ehh.. why are you returning v-n1+NR_END instead of just v when creating a vector?
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  6. #6
    Novice
    Join Date
    Jul 2009
    Posts
    568
    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. #7
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Can you post the complete code that causes segfault?

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    7
    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. #9
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    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. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by msh View Post
    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. #11
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by tabstop View Post
    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. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by msh View Post
    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. #13
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by tabstop View Post
    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. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by msh View Post
    (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. #15
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by tabstop View Post
    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!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with mallocing a 2d array please?
    By Gatt9 in forum C Programming
    Replies: 5
    Last Post: 10-10-2008, 03:45 AM
  2. Replies: 6
    Last Post: 10-21-2003, 09:57 PM
  3. how to pass 2D array into function..?
    By IngramGc in forum C++ Programming
    Replies: 2
    Last Post: 10-21-2001, 08:41 AM
  4. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM
  5. 2d Array access by other classes
    By deaths_seraphim in forum C++ Programming
    Replies: 1
    Last Post: 10-02-2001, 08:05 AM