Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Sep 8th, 2006, 5:39 PM   #1
JawaKing00
Newbie
 
Join Date: Sep 2004
Posts: 29
Rep Power: 0 JawaKing00 is on a distinguished road
Confusion With Pointers and Arrays

Ok, Pointers confuse the heck out of me, and pointers to arrays only make things worse.

Right now, I've got a number of two dimensional arrays of structures where one of the elements of the structure is a string array. On startup, depending on the configuration of the system, only one of the arrays will be used. I need to handle this by using a pointer to point to that array.

Basically I have no clue how to set up that pointer to correctly point to that array. Here is an example of my situation:

// The structure (INT8U is an unsigned 8 bit character)
typedef struct
{
    INT8U ID;
    INT8U AnotherValue;
    INT8U NameString[20];
} ITEM_DEFINE_t;

// The first array
ITEM_DEFINE_t FirstItemDefinitionArray[2][4] = 
{
    {
        {0,  1,  "First Item"},
        {1,  1,  "Second Item"},
        {2,  1,  "Third Item"},
        {3,  1,  "Fourth Item"},
    },
    {
        {0,  2,  "First Item"},
        {1,  2,  "Second Item"},
        {2,  2,  "Third Item"},
        {3,  2,  "Fourth Item"},
    }
};

// The second array
ITEM_DEFINE_t SecondItemDefinitionArray[2][4] = 
{
    {
        {0,  3,  "First Item"},
        {1,  3,  "Second Item"},
        {2,  3,  "Third Item"},
        {3,  3,  "Fourth Item"},
    },
    {
        {0,  4,  "First Item"},
        {1,  4,  "Second Item"},
        {2,  4,  "Third Item"},
        {3,  4,  "Fourth Item"},
    }
};

// Ok this is one part of the problem.
// How do I define the pointer to correctly reference the array?
ITEM_DEFINE_t **ItemPointer;

// This is the next part.
// How do I correctly set the pointer to reference the array?
ItemPointer = SecondItemDefinitionArray;

// The final part, and the part that I have the least problem with
// How do I correctly reference a member in the structure that the pointer is pointing too?
printf ("%s", ItemPointer[1][1]->NameString);

Any help would be hugely appreciated. Like I said, Pointers confuse me to no end.
JawaKing00 is offline   Reply With Quote
Old Sep 8th, 2006, 5:51 PM   #2
Jimbo
Battle Programmer
 
Jimbo's Avatar
 
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 770
Rep Power: 3 Jimbo is on a distinguished road
I'd recommend reading either Narue's tutorial or Dawei's tutorial. If you can spare the time, read both
Jimbo is offline   Reply With Quote
Old Sep 8th, 2006, 6:31 PM   #3
synchronized
Newbie
 
Join Date: Sep 2006
Posts: 5
Rep Power: 0 synchronized is on a distinguished road
I think a quick tutorial is in order. Its not that hard just getting to understand the syntax for a novice can be hard. Here I go.

I will start with a 1 dimensional array. A string will do as I am not feeling too creative tonight.

#include <stdio.h>

int main()
{
    char MyArray[] = "Hello World"; 
    
    //To get to the fist element using the [] notation you would do this
    printf("%c\n", MyArray[0]);

    //That would print n, but what if i wanted to use a pointer to 
    //do the same thing
    printf("%c\n", *(MyArray)); 
    //That will produce the same result as before printing a "H"

    //Now what if i wanted to get to the second character(second index)
    printf("%c\n", MyArray[1]);
    printf("%c\n", *(MyArray + 1));
    //All i did here was add one to the address and C is smart enough to
    //move the pointer along to the start of the next value. It does not matter
    // if the size of each element is one byte or 10 bytes it will always work.
}

So that was one dimensional arrays, but what if you want two dimensions

#include <stdio.h>

int main()
{
    char MyArray[3][3] = {
                                     {'1', '2', '3'}
                                     {'4', '5', '6'}
                                     {'7', '8', '9'}
                                  };
    //First lets look at the address of MyArray
    printf("%p\n", MyArray);
    //Now lets look at the adress of MyArray[0][0]
    printf("%p\n", &MyArray[0][0]);
    //Now lets see what is in MyArray[0]
    printf("%p\n", MyArray[0]);

    //If you run that code what will be printed?

   //They will all print the same memory address as simple a 2D array
   // is just an array of arrays. 

   //Take a look at the values in MyArray

   printf("%c\n", MyArray[0][0]);
   printf("%c\n", *MyArray[0]);
   printf("%c\n", **MyArray);
  
   //This should all print 1 as they all refer to the same location. 

 
}

So this is all the ways to get at the elements in MyArray

MyArray[0][0] = *MyArray[0] = **MyArray
MyArray[0][1] = *(MyArray[0]+1) = *(*MyArray+1)
MyArray[0][2] = *(MyArray[0]+2) = *(*MyArray+2)
MyArray[1][0] = *(MyArray[0]+3) = *(*MyArray+3) = *MyArray[1]
MyArray[1][1] = *(MyArray[0]+4) = *(*MyArray+4) = *(MyArray[1]+1)
MyArray[1][2] = *(MyArray[0]+5) = *(*MyArray+5) = *(MyArray[1]+2)
MyArray[2][0] = *(MyArray[0]+6) = *(*MyArray+6) = *MyArray[2] = *(MyArray[1] + 3)
MyArray[2][1] = *(MyArray[0]+7) = *(*MyArray+7) = *(MyArray[2]+1) = *(MyArray[1] + 4)
MyArray[2][2] = *(MyArray[0]+8) = *(*MyArray+8) = *(MyArray[2]+2) = *(MyArray[1] + 5)

So you can see the pattern and how it works. I will leave it for someone else to make some contrive example for a 2D array.

If i have made a silly error then please feel free to kill me :p

Last edited by synchronized; Sep 8th, 2006 at 6:56 PM.
synchronized is offline   Reply With Quote
Old Sep 8th, 2006, 8:33 PM   #4
Adak
Hobby Coder
 
Join Date: May 2006
Posts: 59
Rep Power: 0 Adak is an unknown quantity at this point
Quote:
Originally Posted by JawaKing00
Ok, Pointers confuse the heck out of me, and pointers to arrays only make things worse.

Right now, I've got a number of two dimensional arrays of structures where one of the elements of the structure is a string array. On startup, depending on the configuration of the system, only one of the arrays will be used. I need to handle this by using a pointer to point to that array.

Basically I have no clue how to set up that pointer to correctly point to that array. Here is an example of my situation:

Any help would be hugely appreciated. Like I said, Pointers confuse me to no end.
Internally, C handles array as with pointers. But that's internally - YOU can just use the array's name and element number, and off you go.

Pointers are wonderful, and very powerful, but if they're leading you into great confusion, just use them very sparingly. When you're working with a 2d array, pointer notation in your code does NOT help it's clarity, one bit. Array[2]2], is infinitely clearer than any other notation, including pointer.

Adak
Adak is offline   Reply With Quote
Old Sep 9th, 2006, 5:53 AM   #5
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by synchronized View Post
If i have made a silly error then please feel free to kill me :p
Aside from trivial syntax errors, all your code appears to be correct. However, it does not answer the original posters question, which essentially boils down to why this piece of code does not work:
c Syntax (Toggle Plain Text)
  1. my_type** pointer_to_2d_array = my_2d_array;
At first, I didn't understand what was wrong either. It seems logical, after all. And from this logical approach I would infer that JawaKing00 knows more than people are giving him credit for.

JawaKing00 appears to understand the fact that a 2D array is simply an array of arrays, and he comprehends that a pointer can be assigned to an array. What he slips up on is to assume that arrays and pointers are the same thing.

The correct approach can be inferred by DaWei's excellent and knowledgable guide to pointers. However, as far as I can see, the correct way of pointing to a 2D array is ever explicitly mentioned, so I'll mention it now. This is partially for JawaKing00's benefit, partially for mine; if I'm incorrect, I'd like to know about it!
c Syntax (Toggle Plain Text)
  1. ITEM_DEFINE_t (*ItemPointer)[4];
  2. ItemPointer = SecondItemDefinitionArray;
  3. printf ("%s", ItemPointer[1][1].NameString);
Arevos is offline   Reply With Quote
Old Sep 9th, 2006, 8:37 AM   #6
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,260
Rep Power: 5 grumpy will become famous soon enough
The relationship between pointers and arrays trips everyone up sometime. Heck, I typed a response to a question about passing multi-dimensional arrays to functions a couple of days back, and got it wrong too (that was at the end of a stressful couple of weeks, which started with undergoing knee surgery and then the pain of recovery and physiotherapy to get walking again). I can't find the thread at the moment, but I think Narue corrected my error.

The links to both Narue's and Dawei's tutorials given above are good, and should be read over and over again. They both cover the key issues quite well, although they are written in different styles that may suit different people.

As Arevos has said, arrays are different things from pointers. However, C treats pointers and arrays as equivalent (i.e. interchangeable) in some contexts.

A pointer is a variable that can contain the address of another variable. For example, a pointer to int can contain the address of an int. For example;
int main()
{
     int x;
     int *px = &x;      /* px contains the address of x  */
     *px = 2;            /*  sets x to be 2   */
}
Note that there is no array in the above. However, if we have an array, the name of that array is (in the beloved programming language called C) treated by the compiler as the address of the first element in that array. For example;
int main()
{
     int array[5];
     int *px = x;        /* px contains the address of x[0] */
     *px = 2;            /*  sets x[0] to be 2   */
     *(px + 1) = 5     /*  sets x[1] to be 5 */
     px[1] = 5;         /*  does exactly the same thing as the previous line */
}
This example illustrates the equivalence of an array to a pointer. But, if we do this;
int main()
{
     int *px;             /* px is an uninitialised pointer */
     *px = 2;            /*  sets the value pointed at by px to be 2 */
     px[0] = 2;          /*   same as previous line */
}
This code actually yields undefined behaviour, as px has been uninitialised, so does not point at anything. This means that computing *px (or, equivalently, px[0]) could do anything. Assigning the result of either expression to 2, as in the above example, typically yields strange behaviour (eg a program crash). px is a pointer, but it is NOT an array.

Multi-dimensional arrays are where this breaks down. A multi-dimensional array is an array of arrays, but (as of the 1989 C standard) it is not equivalent to a pointer to a pointer. In some contexts, it can be treated as a pointer to an array. For example;
int main()
{
     int x[3][4];    /* an array of 3 arrays of 4 ints */
     int (*px)[4];  /*  a pointer to an array of 4 ints */
     px = x;         /*  OK;  px is now an alias for x */
     px[1][2] = 5; /*  Sets x[1][2] to be 5 */
}
The brackets in the declaration of px mean we are declaring a pointer to an array of 4 int. Leave out the brackets, and we would have declared an array of 4 pointers to int -- which are different things BECAUSE this is an example of where pointers and arrays ARE DIFFERENT. The compiler would then have complained bitterly about the assignment "px = x" (with a message to the effect that px and x have different types).

Where things get a little squirrelly (and can trip up people - like myself - who used C before there was a standard) is that pre-standard versions of C did not recognise an array as a distinct type, so allowed an implicit conversion of an "array of array" to "pointer to pointer". That caused a lot of headaches for programmers (as compilers would not complain about some of those conversions when they really should have, and the program would simply crash for no obvious reason). One of the great services done by the committee that produced the 1989 C standard was that they disallowed this conversion. The trade-off is that most things relating to multi-dimensional arrays in C are difficult to get right, because compilers complain bitterly if the syntax is not "just so". But a whining compiler is much better for a programmer sanity than code which "looks right, compiles OK, but crashes for the end user": end users tend to complain more loudly than compilers.
grumpy is offline   Reply With Quote
Old Sep 12th, 2006, 11:13 AM   #7
JawaKing00
Newbie
 
Join Date: Sep 2004
Posts: 29
Rep Power: 0 JawaKing00 is on a distinguished road
Quote:
Originally Posted by Arevos View Post
JawaKing00 appears to understand the fact that a 2D array is simply an array of arrays, and he comprehends that a pointer can be assigned to an array. What he slips up on is to assume that arrays and pointers are the same thing.

The correct approach can be inferred by DaWei's excellent and knowledgable guide to pointers. However, as far as I can see, the correct way of pointing to a 2D array is ever explicitly mentioned, so I'll mention it now. This is partially for JawaKing00's benefit, partially for mine; if I'm incorrect, I'd like to know about it!
c Syntax (Toggle Plain Text)
  1. ITEM_DEFINE_t (*ItemPointer)[4];
  2. ItemPointer = SecondItemDefinitionArray;
  3. printf ("%s", ItemPointer[1][1].NameString);
That appears to work perfectly. Thank you very much!

I still don't quite understand why, though. I read through both of those tutorials, and I do have a passing knowledge of pointers and arrays, but sometimes they just make my head hurt. I get that that is a pointer to an array of structures, but why is there only one dimension? Wouldn't
c Syntax (Toggle Plain Text)
  1. ITEM_DEFINE_t (*ItemPointer)[2][4];
seem to make more sense? It would to me, but that doesn't work.

Also, why do we need to use the '.' and not '->' when accessing a member of the structure in that array? I thought when using a pointer, that the '->' notation was used, but again that doesn't work.

Finally, why do we initialize the pointer as the whole array and not the address of the array? I would expect something like
c Syntax (Toggle Plain Text)
  1. ItemPointer = &SecondItemDefinitionArray[0][0];
and not
c Syntax (Toggle Plain Text)
  1. ItemPointer = SecondItemDefinitionArray;

I guess my inexperience with pointers to arrays is showing here, but I'd like to know more about the reasoning behind this. Especially since I'll probably need to explain it to the lead engineer on the project, since he doesn't appear to fully understand this implementation either

Thank you again for all the help. It has been incredibly useful.
JawaKing00 is offline   Reply With Quote
Old Sep 12th, 2006, 1:15 PM   #8
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by JawaKing00 View Post
I get that that is a pointer to an array of structures, but why is there only one dimension? Wouldn't
c Syntax (Toggle Plain Text)
  1. ITEM_DEFINE_t (*ItemPointer)[2][4];
seem to make more sense? It would to me, but that doesn't work.
In order to get a pointer of an array, we must assign the address of the first element of the array to a pointer of the appropriate type. Thus, if we have an array of ints, then we can assign a pointer to it in the following manner:
c Syntax (Toggle Plain Text)
  1. int *p = &(array_of_ints[0])
Or, more concisely:
c Syntax (Toggle Plain Text)
  1. int *p = array_of_ints
Now, you already know, I presume, that a 2D array is merely an array of arrays. Thus, instead of an int pointer, we'd need an int array pointer:
c Syntax (Toggle Plain Text)
  1. int (*p)[5] = two_dimentional_array_of_ints
Even though C can convert an array into a pointer, it is not clever enough to convert a pointer to an array into a pointer to a pointer. That's why we need to have a pointer to an array, or (*p)[n].

Quote:
Originally Posted by JawaKing00 View Post
Also, why do we need to use the '.' and not '->' when accessing a member of the structure in that array? I thought when using a pointer, that the '->' notation was used, but again that doesn't work.
Your array contains ITEM_DEFINE_t, and not ITEM_DEFINE_t*, which is why you need a . and not a ->.
Arevos is offline   Reply With Quote
Old Sep 13th, 2006, 1:56 PM   #9
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
If you want to see the difference between an array name used as a pointer, and the usage of a pointer to the same array, simply write the two instructions (which look identical) and examine the emitted assembly code. In many cases the compiler babies us (at the cost of some confusion). After all, we all know we can't assign to arrays, but we all write char myStuff [] = "ABC";.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Sep 14th, 2006, 6:11 AM   #10
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,260
Rep Power: 5 grumpy will become famous soon enough
Dawei, an assignment for you: write on the blackboard 100 times "Dawei should not tell lies".
grumpy is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Arrays, Pointers, and Constants JawaKing00 C 4 May 31st, 2006 2:19 PM
strings, pointers, arrays bl00dninja C++ 21 Mar 15th, 2006 9:02 AM
n00b question(s) about arrays, pointers, and functions keweedsmo C++ 8 Feb 9th, 2006 2:46 PM
Pointers in C (Part II) Stack Overflow C 2 Apr 29th, 2005 11:39 AM
Pointers in C (Part I) Stack Overflow C 4 Apr 28th, 2005 8:03 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 7:35 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC