Thread: Function to print arbitrary integer array

  1. #1
    Registered User
    Join Date
    Feb 2013
    Posts
    10

    Function to print arbitrary integer array

    Hi,
    There seems to be a problem with this function which is supposed to print any integer array passed to it.
    Code:
    void print_int_matrix(int *arb_array,int num_rows,int num_columns)
    {
       int i,j;
       for(i=0;i<num_rows;i++)
       {
           for(j=0;j<num_columns;j++)
           {
               printf("%d, ", *(arb_array + (i*num_columns + j)));
            
           }
           printf("\n");
       }
    }
    This is printing out some values okay, but some are completely wrong, as if its getting corrupted data. Is there a logical flaw I'm not catching. Also, I'm only using pointer arithmetic here because I couldn't get indexing ( i.e. arb_array[x][y]) to work. Is there a way to use indexing on arrays passed to functions?

    Thanks for any input

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I ran a quick test on this function, and it appears to print out the test case I wrote just fine. Can you be more specific about how the output is corrupted? Perhaps write out a small "main()" function for us that compiles and exhibits the problem you're seeing?

    I'm only using pointer arithmetic here because I couldn't get indexing ( i.e. arb_array[x][y]) to work. Is there a way to use indexing on arrays passed to functions?
    I believe that once you go beyond single dimensional arrays, there is no way to avoid using pointer arithmetic as you have done here. Someone else here will correct me if I'm mistaken about this.

  3. #3
    Registered User
    Join Date
    Feb 2013
    Posts
    10
    Thanks Matticus,
    Yes, it's a bit confusing as it sometimes seems to work okay, as evidently it did for you. Here's a lead-in to where it malfunctions. The following loads/converts a character array to an integer array using atoi.

    Code:
    for(i=0;i<NUM_NOUNS;i++)
     {
        for(j=0;j<NUM_VERBS;j++)
        {
          nv_matrix[i][j]=atoi(my_array[i][j]);
          // printf("%d ",nv_matrix[i][j]);
    
        }
       printf("\n");
     }
    If you enable the printf statement it will print out the converted values correctly. But when you call the aforementioned function like this

    Code:
    print_int_matrix((int *)nv_matrix,NUM_NOUNS,NUM_VERBS);
    it will then produce corrupted values. I've tried it on two compilers and both produce the corrupted results. I'm sure there is some logical error here I'm just not catching.

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    As requested, if you could provide a complete sample program that we can compile, that still exhibits the problem you're seeing, it would make it a lot easier for us to assist.

    If "nv_matrix" is of type int, try passing it to the function like so:

    Code:
    print_int_matrix(&nv_matrix[0][0],NUM_NOUNS,NUM_VERBS);

  5. #5
    Registered User
    Join Date
    Feb 2013
    Posts
    10
    Hi,
    Thanks for your input, here's a full working example:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <string.h>
    
    #define MAX_SOURCE_LINE_LENGTH 256
    #define NUM_NOUNS 6
    #define NUM_VERBS 4
    
    
    static void assign_matrix_vals(char *p[][6],char *z);
    int extract_str_left(char *return_str, char *orig_str, int num_chars, int str_pos);
    void restore_matrix(int arb_array[],int num_rows,int num_columns, int restore_num);
    void print_int_matrix(int arb_array[],int num_rows,int num_columns); 
    
    int main(int argc, char *argv[])
    {
    
    
      int nv_matrix[NUM_VERBS][NUM_NOUNS];
    
    
    
      char extracted_str[20];
      char *p_extracted_str;
      char *my_array[NUM_VERBS][NUM_NOUNS];
      int i,j,l,m,n;
    
      p_extracted_str=extracted_str;
     assign_matrix_vals(my_array,"2000");
    
      for(i=0;i<NUM_NOUNS;i++)
     {
        for(j=0;j<NUM_VERBS;j++)
        {
          nv_matrix[i][j]=atoi(my_array[i][j]);
          // printf("%d ",nv_matrix[i][j]);
    
        }
       printf("\n");
     }
    
    
     print_int_matrix((int *)nv_matrix,3,3);
    
      system("PAUSE");
      return 0;
    }
    
    
    int extract_str_left(char *return_str, char *orig_str, int num_chars, int str_pos)
    {
        int i, position;
        if((num_chars > strlen(orig_str))||(num_chars <=0)) return 1;
         position=str_pos-num_chars+1;
    
      for (i=0;i<num_chars-1;i++)
    
       {
         return_str[i]=orig_str[position+i];
       }
      return_str[num_chars-1]='\0';
      return 0;
    }
    
    void restore_matrix(int *arb_array,int num_rows,int num_columns, int restore_num)
    {
         int i;
         for(i=0;i<(num_rows*num_columns);i++)
         {
            *(arb_array + i)=restore_num;
         }
    }
    
    void print_int_matrix(int *arb_array,int num_rows,int num_columns)
    {
       int i,j;
       for(i=0;i<num_rows;i++)
       {
           for(j=0;j<num_columns;j++)
           {
               printf("%d, ", *(arb_array + (i*num_columns + j)));
              //  printf("%d ", arb_array[i][j]);
           }
           printf("\n");
       }
    }
    
    static void assign_matrix_vals(char *p[][6], char *z)
    {
         int i,j;
         for(i=0;i<NUM_NOUNS;i++)
         {
            for(j=0;j<NUM_VERBS;j++)
            {
               p[i][j]=z;
    
    
            }
         }
    
    }
    There's extraneous stuff there but it runs.

  6. #6
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    It's a mistake to convert an int[?][?] to a int * in the first place. If you have 10 rows and 15 columns, define your array like this:

    int x[10 * 15];

    Then call your function like so:

    print_int_matrix(x, 10, 15);

    edit: s/int[?][?]/int (*)[?]/
    Last edited by Barney McGrew; 02-21-2013 at 03:34 PM.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    It's a mistake to convert an int[?][?] to a int * in the first place.
    Not really. As long as you point to the first element you can traverse them like a one dimensional array if you can do the math. They are guaranteed to be stored in a contiguous manner.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    It would appear that your biggest problem is that you have the array indices referenced backwards in several places. Since each are of different sizes, you will be overrunning the bounds of the array.

    Code:
    #define NUM_NOUNS 6
    #define NUM_VERBS 4
    
    int nv_matrix[NUM_VERBS][NUM_NOUNS];    // nv_matrix[4][6]
    char *my_array[NUM_VERBS][NUM_NOUNS];   //  my_array[4][6]
    
    
      for(i=0;i<NUM_NOUNS;i++)
      {
        for(j=0;j<NUM_VERBS;j++)
        {
          nv_matrix[i][j]=atoi(my_array[i][j]);  // tries to access "nv_matrix[5][]" and "nv_matrix[6][]"
          //printf("%d ",nv_matrix[i][j]);       // ditto for "my_array"
        }                                        // this leads to buffer overruns!
       printf("\n");
      }
    
    // in the "for()" loop:
    //    i = first  dimension = NUM_NOUNS
    //    j = second dimension = NUM_VERBS
    After you correct these, apply the fix I suggested in post #4.

  9. #9
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    @whiteflags: int * and int (*)[?] aren't compatible types. Also, while it might seem fine to pass x[0] to print_int_matrix instead, there's this point in section J.2 (undefined behaviour) of the specification: "An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5])(6.5.6)."

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Barney McGrew View Post
    @whiteflags: int * and int (*)[?] aren't compatible types.
    Then why did you write:

    It's a mistake to convert an int[?][?] to a int * in the first place.
    I would appreciate it if you did not blame me for your mistakes.

  11. #11
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Well, I fixed one mistake in my first post earlier:
    edit: s/int[?][?]/int (*)[?]/

    Aside from that, dunno what you're referring to. Care to elaborate?

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I have nothing to elaborate on.

    edit: s/int[?][?]/int (*)[?]/
    Obviously I missed this. Sorry. It is far better to actually edit the text, don't you think?

  13. #13
    Registered User
    Join Date
    Feb 2013
    Posts
    10
    Thanks Matticus, I wasn't looking closely enough at those loop limits. That explains the overruns. With that fixed it works fine. Yes, I did try referencing it as

    &nv_matrix[0][0]
    and it worked the same. I like this as it lays bare what you are doing which is passing the address of the first element in the array.

    @Barney, I try to use 'normal' ([x][y]) indexing as much as possible because it's easier for me to follow though I recognize you can represent a matrix as a one dimensional array, which is how the computer understands it. (BTW I was confused by 'edit: s/int[?][?]/int (*)[?]/' as well but was waiting to see if someone would comment on it!)

    Thanks all for the help.

  14. #14
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    It has its advantages and disadvantages. If you change the text then it's advantageous if people quote your text after you've fixed the mistake, since it avoids things like this. On the other hand, if they quote your text before you fix the mistake it can be fairly confusing.

  15. #15
    Registered User
    Join Date
    Feb 2013
    Posts
    10
    Yes, even looking at this for a minute I can't quite figure out what the edit is, though I'm guessing the notation is accepted. I think putting the original and the corrected in separate quote tags would make it much clearer. JMHO!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 12-23-2011, 04:49 PM
  2. Replies: 4
    Last Post: 11-28-2011, 03:39 PM
  3. Passing array of arbitrary dimension
    By twinbee in forum C Programming
    Replies: 12
    Last Post: 04-03-2008, 07:21 PM
  4. print array member function
    By brianptodd in forum C++ Programming
    Replies: 4
    Last Post: 11-11-2003, 11:45 PM
  5. Array sizes and arbitrary sized arrays
    By bennyandthejets in forum C++ Programming
    Replies: 3
    Last Post: 07-03-2003, 11:24 PM

Tags for this Thread