#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0

    Defining and initialization of array using pointers


    Please go through this code :


    /*
    main()
    {

    int i, *a;
    *a =10;
    *(a+1) = 3;
    *(a+2) =6;

    for (i=0; i<3; i++ )
    printf("%d\n", a[i]);
    getch();
    } */


    I think this is one way of defining and initializing a 1D array
    or is there any difference in the classic way of initializing the array i.e
    int arr[] = {10,3,6};

    Also, how can a 2D array be defined and initialized in the similar manner using pointers ??

    Thanks...
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    Well given that your 'pointer' method uses an uninitialised pointer, perhaps you should begin by addressing that issue, before trying something complicated like 2D arrays.

    Also, initialisation is not the same thing as assignment.

    *a = 10;
    is assignment,

    whereas
    char a[] = { 10 };
    is initialisation.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0
    isn't it right to say that assigning values of same type and size to contagious memory locations ( using pointers ) creates an array ?

    if yes, how is it possible to assign values in similar manner to create a 2D array ?
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    Assignment doesn't create anything.

    At the very least, you need to begin with
    int *a = malloc( 3 * sizeof(int) );
    Then you can do
    *a = 10;
    *(a+1) = 20;
    *(a+2) = 30;


    The fact that you can also do
    a[0] = 10;
    a[1] = 20;
    a[2] = 30;

    doesn't take away the need to allocate the memory in the first place, or magically change the pointer into an array.

    Read this since you seem to be confused about the whole pointer/array relationship.

    > if yes, how is it possible to assign values in similar manner to create a 2D array ?
    It is, but I'm not going to say how until you're OK on just one dimension.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0
    great link.. going through it..

    may bother u again if I get stuck..
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0
    read about allocating memory and understood the need to use malloc or calloc ....

    a little confusion..
    why would this code work ??

    /*
    main()
    {

    int i, *a;
    *a =10;
    *(a+1) = 3;
    *(a+2) =6;

    for (i=0; i<3; i++ )
    printf("%d\n", a[i]);
    getch();
    } */
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    > why would this code work ??
    Pure dumb luck.

    - Today, it works.
    - Tomorrow, it crashes.
    - Next week - where the !$?" are my OS install disks!?

    Not a lot can happen in a user land process; the OS will kill off any process trying to access illegal memory.

    But if you were programming a kernel mode driver, or writing code for a bare board, then all bets are off. Pretty much anything can happen, including causing physical damage to hardware (the kind that involves spending money to replace).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0
    I tried to dynamically allocate a 2D array :

    code:
    /*
    main()

    {
    int **arr,x,y,i,j;
    x=5;
    y=2;
    arr = malloc ( x * sizeof(int*));
    for (i=0; i<x; i++)
    {
    *(arr+i) = (int*)malloc(y*sizeof(int));
    }
    for (i=0; i<x; i++)
    {
    for (j=0; j<y; j++)
    {
    printf ("\n%d", &arr[i][j]);
    }
    }

    getch();

    } */

    Output :

    8720136
    8720140
    8720272
    8720276
    8720288
    8720292
    8720304
    8720308
    8720320
    8720324

    I see that memory isn't contiguous, why should it be called an array then ?
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    Well arr itself is contiguous, as is each arr[i]
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,174
    Rep Power
    2222
    Originally Posted by check.wsx
    I tried to dynamically allocate a 2D array :
    First, use code tags!!!!

    Code:
    main()
    {
        int **arr,x,y,i,j;
        x=5;
        y=2;
        arr = malloc ( x * sizeof(int*));
        for (i=0; i<x; i++)
        {
            *(arr+i) = (int*)malloc(y*sizeof(int));
        }
        for (i=0; i<x; i++)
        {
            for (j=0; j<y; j++)
            {
                printf ("\n%d", &arr[i][j]);
            }
        }
                 
        getch();
                 
    }
    If you don't use code tags, then you lose all formatting. That makes your code unreadable and hence we cannot feel bothered to attempt to read it.

    Sheesh!

    Originally Posted by check.wsx
    I see that memory isn't contiguous, why should it be called an array then ?
    If you had declare it as a proper 2D array, then you should expect it to be contiguous. What do you find in such a case?

    Since you had codged it together out of bits and pieces in the heap, what do you expect?

    Each row you had malloc'd out of the heap should be contiguous. Since each row had been malloc'd from wherever, why should you expect those rows to be contiguous to each other?

    What do you expect? Do you understand what is happening? Why do you expect what you expect? That is not a rhetorical question!
  20. #11
  21. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,113
    Rep Power
    1803
    Originally Posted by check.wsx
    I see that memory isn't contiguous, why should it be called an array then ?
    It is not; it is an array of pointers to arrays. It is not the same as an array in the sense the language defines an array, but can nonetheless be accessed using array notation.

    To achieve a contiguous block so that it is equivalent to a built-in array, you would allocate a single contiguous block of size x*y*sizeof(int), then assign arr with pointers into that block.

    Also prefer initialisation to separate declaration and assignment, prefer array notation to pointer arithmetic where possible, and strictly %p is the correct format specifier for a pointer not %d:

    C Code:
     
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        int x = 5 ;
        int y = 2 ;
        int* memblock = malloc( x * y * sizeof(*memblock) ) ;
        int** arr = malloc ( x * sizeof(*arr) ) ;
        int i, j ;
     
        for( i = 0; i < x; i++ )
        {
            arr[i] = &memblock[i * y] ;
        }
     
        for( i = 0; i < x; i++ )
        {
            for( j = 0; j < y; j++ )
            {
                printf( "\n%p", &arr[i][j] ) ;
            }
        }
     
        return 0 ;
    }
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    6
    Rep Power
    0
    Originally Posted by salem

    > if yes, how is it possible to assign values in similar manner to create a 2D array ?
    It is, but I'm not going to say how until you're OK on just one dimension.
    Now that I am Ok wid one dimension, it's time....
    wanna try your version as well..
  24. #13
  25. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    OK, here are various ways of allocating, using and freeing 2D arrays.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ROWS 5
    #define COLS 10
    
    // Allocate arrays
    // ---------------
    
    // Allocate an array to store all the pointers to the rows,
    // then allocate for each row.
    int **allocPointerToPointer ( int rows, int cols ) {
      int r;
      int **result = malloc( rows * sizeof(*result) );
      for ( r = 0 ; r < rows ; r++ ) {
        result[r] = malloc( cols * sizeof(*result[r]) );
      }
      return result;
    }
    
    // Allocate an array to store all the pointers to the rows,
    // then allocate for all the data in a single contiguous block
    // Then loop to manually partition the data block for each row
    // Use it in the same way as anything allocated with allocPointerToPointer
    // but it needs a different free function.
    int **allocPointerToPointerContiguous ( int rows, int cols ) {
      int **result = malloc(rows*sizeof(*result));
      int *data = malloc(rows*cols*sizeof(*data));
      int r;
      for ( r = 0 ; r < rows ; r++ ) {
        // note: the first row is also a pointer to the whole
        // block, which is used when it comes to freeing it.
        result[r] = data;
        data += rows;
      }
      return result;
    }
    
    // Allocate rows of [COLS] arrays
    // Use this when the minor dimensions are a compile time constant.
    int (*allocPointerToArray(int rows))[COLS] {
      int (*result)[COLS] = malloc( rows * sizeof(*result) );
      return result;
    }
    
    
    // Free arrays
    // -----------
    // These just match the previous mallocs.
    void freePointerToPointer ( int **p, int rows ) {
      int r;
      for ( r = 0 ; r < rows ; r++ ) {
          free( p[r] );
      }
      free( p );
    }
    void freePointerToPointerContiguous ( int **p ) {
      free( p[0] );
      free( p );
    }
    void freePointerToArray ( int (*p)[COLS] ) {
      free( p );
    }
    
    
    // Initialise contents of arrays
    // -----------------------------
    // Notice how the loop construct is identical in all cases.
    void initPointerToPointer ( int **p, int rows, int cols ) {
      int r,c;
      for ( r = 0 ; r < rows ; r++ ) {
        for ( c = 0 ; c < cols ; c++ ) {
          p[r][c] = r * c;
        }
      }
    }
    void initPointerToArray ( int (*p)[COLS], int rows ) {
      int r,c;
      for ( r = 0 ; r < rows ; r++ ) {
        for ( c = 0 ; c < COLS ; c++ ) {
          p[r][c] = r * c;
        }
      }
    }
    
    
    // Print contents
    // --------------
    // Notice how the loop construct is identical in all cases.
    // Rather than [r][c], I've used pointer notation instead just for effect
    void printPointerToPointer ( int **p, int rows, int cols ) {
      int r,c;
      int *q;
      for ( r = 0 ; r < rows ; r++, p++ ) {
        for ( c = 0, q = *p ; c < cols ; c++, q++ ) {
          printf("%2d ", *q);
        }
        printf("\n");
      }
      printf("\n");
    }
    void printPointerToArray ( int (*p)[COLS], int rows ) {
      int r,c;
      int *q;
      for ( r = 0 ; r < rows ; r++, p++ ) {
        for ( c = 0, q = *p ; c < COLS ; c++, q++ ) {
          printf("%2d ", *q);
        }
        printf("\n");
      }
      printf("\n");
    }
    
    int main(void)
    {
      int a1[ROWS][COLS];
      int (*a2)[COLS] = allocPointerToArray(ROWS);
      int **a3 = allocPointerToPointer(ROWS,COLS);
      int **a4 = allocPointerToPointerContiguous(ROWS,COLS);
      
      initPointerToArray(a1,ROWS);
      initPointerToArray(a2,ROWS);
      initPointerToPointer(a3,ROWS,COLS);
      initPointerToPointer(a4,ROWS,COLS);
      
      printPointerToArray(a1,ROWS);
      printPointerToArray(a2,ROWS);
      printPointerToPointer(a3,ROWS,COLS);
      printPointerToPointer(a4,ROWS,COLS);
      
      // no need to free a1, it's just an array
      freePointerToArray(a2);
      freePointerToPointer(a3,ROWS);
      freePointerToPointerContiguous(a4);
      
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo