Array pointers

This is a discussion on Array pointers within the C Programming forums, part of the General Programming Boards category; I use a pointer to cycle through a 2D char array (8x8) as if it were a 1D (0-63), but ...

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    119

    Array pointers

    I use a pointer to cycle through a 2D char array (8x8) as if it were a 1D (0-63), but i'm not sure how to do the following. I want to evaluate each character that the pointer is pointing too, and possibly even print it, depending on what it is. I perform the following cast but get this error when compiling. warnign: cast from pointer to integer of diffrent size, I get it twice for both casts. I can still create the program but I don't want any warnings/errors. If I'm way off, can someone help me out, I just want to access and analyze the data the pointer is pointing too.

    Code:
    //just an example i jotted down quickly
    
    char board[8][8];
    arrayPtr = &board[0][0];
    
    i=0;
    while ( i < 63 )
    {
        if ( (char)arrayPtr++ == 'X' )
        {
            //do something
         }
        else
        {
            printf( " %c ", (char)arrayPtr++ ); 
        }
    
    i++;
    }

  2. #2
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    982
    As a note, it's probably technically undefined behavior to do what you're doing. In a dusty corner of the C standard, you'll find that
    Code:
    arrayPtr = (char*)&board;
    is likely slightly more correct, if only in theory. It's not really pretty either way.

    Anyhow, the problem you're seeing is because you're treating arrayPtr as a char, when it's a pointer to char (so I assume, since you didn't show its declaration). Try using
    Code:
    *arrayPtr++
    instead of what you have. No cast necessary or recommended.

    In addition, you're incrementing the pointer too much. Try something like:
    Code:
    for(i = 0; i < 64; i++)
    {
      char c = *arrayPtr++;
      if(c == 'X')
      /* and so on */
    }
    In the original, arrayPtr is incremented twice if *arrayPtr is not 'X'. I also used 64 instead of 63 so the entire array will be printed.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    119
    typing it like this gave me no errors, and I was told is equivalent...can anyone shed some more light on this. Will it work...is it correct etc. Thanks in advance

    Code:
    //just an example i jotted down quickly
    
    char board[8][8];
    arrayPtr = &board[0][0];
    char ch;
    
    i=0;
    while ( i < 64 )
    {
        ch = arrayPtr[ i++ ];
        if ( ch == 'X' )
        {
            //do something
         }
        else
        {
            printf( " &#37;c ", ch ); 
        }
    }

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    No, this is perfectly defined behaviour. I'm almost certain that multidimensional arrays are guaranteed to be contiguous in memory. And a cast certainly won't improve things because you're casting from and to the exact same type.

    Your second code is better; your original code lacked an asterisk as indicated and incremented arrayPtr twice.

    Your latest code will work, and it is correct. Why does it work? Because
    Code:
    char array[8][8];
    and
    Code:
    char array[64];
    both take the same amount of memory. They're really exactly the same; C just lets you index the first array with multiple indicies to aid ease of use. You can use a 2D array as a 1D array as you have done, and you can also use a 1D array as a 2D array.
    Code:
    char array[64];
    array[i * 8 + j] = 3;
    is the same as
    Code:
    char array[8][8];
    array[i][j] = 3;
    Of course, C introduced the multidimensional array syntax to make your life easier. There's no functional difference.

    If you've every programmed in DOS mode 13h you'll know exactly what I'm talking about. You probably haven't, though. Anyway, you basically take a 1D array and treat it as a 2D array to access the pixels on the screen, which is of course 2D.

    The only difference between 1D and higher dimensional arrays is in the syntax you use in your program. They have the same representation in memory.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    For writing image data I have noticed that using a single dimension array (in C) can be much faster than a 2D array. Especially where you are iterating through each pixel on your image. EG:
    Code:
    for(y=0; y<h; y++)
    {
        for(x=0; x<w; x++)
        {
              pixel[i] = something;
              i++;
        }
    }
    Would cut out a whole load of unnecessary calculations. For reading image data the speed difference is even more noticeable as to convert from 2D co-ords to 1D modulus and divide are required.

    Strangely in other basic languages I havent noticed a speed difference between using single or multi dimensional arrays.

  6. #6
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    982
    No, this is perfectly defined behaviour. I'm almost certain that multidimensional arrays are guaranteed to be contiguous in memory. And a cast certainly won't improve things because you're casting from and to the exact same type.
    I presume this is in reply to my statement. While arrays are contiguous, it's still not legal to go off the end of one, even if you "know" what's there. The problem with the original code was that the pointer was pointing to one of the subarrays, not the entire object. Of course, on presumably all implementations, there's no difference, which is why I said it was more correct in theory.

    In my example, the cast is definitely necessary, because &board doesn't have the same type as arrayPtr. C does allow you to navigate each byte of an object through a char pointer. It just happens that board and board[0][0] are different objects. It's a nuanced difference. The only time it'd be an issue is if a compiler used very strict bounds checking, which would be legal, if inefficient.

    I imagine you can find arguments on comp.lang.c for both sides; choose whichever suits you.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    I presume this is in reply to my statement. While arrays are contiguous, it's still not legal to go off the end of one, even if you "know" what's there. The problem with the original code was that the pointer was pointing to one of the subarrays, not the entire object. Of course, on presumably all implementations, there's no difference, which is why I said it was more correct in theory.
    I suppose you could say that; you could also argue that you haven't actually gone off of the end of the whole array. I had never thought of it that way before. Perhaps you are right. Like you said, search around and you'll likely find arguments for both sides.

    In my example, the cast is definitely necessary, because &board doesn't have the same type as arrayPtr. C does allow you to navigate each byte of an object through a char pointer. It just happens that board and board[0][0] are different objects. It's a nuanced difference. The only time it'd be an issue is if a compiler used very strict bounds checking, which would be legal, if inefficient.
    Yes, I see what you mean.
    Code:
    arrayPtr = (char*)&board;
    I read over it quickly and thought you were stating that the cast was required in something like this:
    Code:
    arrayPtr = (char*)&board[0][0];
    Which of course it probably isn't. (Assuming that arrayPtr is a char*.)

    Actually, I think that perhaps the code you were looking for was
    Code:
    arrayPtr = (char*)board;
    Just plain &board doesn't really make sense.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    982
    Actually, I think that perhaps the code you were looking for was
    Code:
    arrayPtr = (char*)board;
    Just plain &board doesn't really make sense.
    Well... (char*)board suffers the same (potential) problem that using &board[0][0] does. board is the same, here, as &board[0]; so you're only allowed to look at the first array. In most contexts, the expression board has type "pointer to array of 8 char, whereas &board is "pointer to array of 8 array of 8 char", which is the whole shebang.

    It's still really just a problem in theory (as far as I know) but hey, if it's just as easy to satisfy the standard, regardless of how obtuse it's being, may as well do it.

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,506
    As yet, I haven't seen a good reason for wanting to try using a flattened array.
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Returning an Array of Pointers to Objects
    By randomalias in forum C++ Programming
    Replies: 4
    Last Post: 04-29-2006, 02:45 PM
  2. two-dimensional dynamic array of pointers to classes
    By Timo002 in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 06:18 AM
  3. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 05:58 PM
  4. array of pointers to struct array
    By eth0 in forum C++ Programming
    Replies: 1
    Last Post: 01-08-2004, 05:43 PM
  5. array of pointers to structs
    By stumon in forum C Programming
    Replies: 7
    Last Post: 03-24-2003, 06:13 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21