# array of pointers/pointer arithmetic

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 11-09-2008
tlpog
array of pointers/pointer arithmetic
Long time troll, first time poster... I have some problems understanding arrays containing pointers. Take this fragment for example:
Code:

```        char *a[3];         char d[50] = {'a', 'b', 'c'};         *(*(a + 0) + 0) = *(d + 0);         *(*(a + 0) + 1) = *(d + 1);         *(*(a + 0) + 2) = *(d + 2);         *(*(a + 0) + 3) = *(d + 3);         printf("%c",*(*(a + 0) + 0));         printf("%c",*(*(a + 0) + 1));         printf("%c",*(*(a + 0) + 2));```
Which should print out "abc" without the quotes... The following explanation is shody at best so please bare with me...

From what I understand, array 'a' contains three members of type pointer to a char array. The actual data contained in these 3 memory adresses are actually of type int, where an int represent the address of the actual char array. So take for example the line *(*(a + 0) + 0) = *(d + 0); ...
Starting from the innermost parentheses, the code states--
#1. (a + 0)..... take the starting memory adress of a, that is a[0], and add this to sizeof(type) multiplied by 0... So I am at the level of a[0] which once again contains a pointer to the first element of char array
#2. *(a + 0) + 0..... Now take what a[0] points to, which is the starting address of the first char array, and deference the value, which should now give me the starting address of the single character at the beginning of the char array. Thus *(a + 0) + 1 should be the address of the second member of the char array and so on
#3. *(*(a + 0) + 0) = *(d + 0)..... Finally, deference the address of the char array and give me it's value, which should be of type char, and assign d[i] as it's value;

Now the above only works if I add nothing else to the program, that is-- when i try this with reading lines of text from a file all hell breaks loose. I suspect my pointer arithmetic and logic as detailed above is flawed. If i had to guess, I would say since I did not specify the array size when i declared the variable, the array only contains one single member, so adding sucessive members to char array will work in very limited situations and through side effects -- That is, I am printing the values from beyond my array but since there was nothing there and nothing will go in that address I got away with it.

Now you can probably guess what I am trying to do here...
Code:

```        char *a[3];         char *b[3];         char *c[3];                 char **all[3] = {a,b,c};```
So with one line of code, say *(*(*(all + 1) + 2) + 10), I can tell the program to put whatever data into the 11th character position of array *b[2]. What seemed so simple at first really has me scratching my head. Any corrections to my faulty logic/ suggestions would be appreciated. Thank you.
• 11-09-2008
Salem
> From what I understand, array 'a' contains three members of type pointer to a char array.
So far, so good.
However, the rest of it is off in the weeds somewhere.
Your use of "int" is just plain wrong I'm afraid.

The first problem is that although the type is correct, you didn't actually do something like
a[0] = some_block_of_memory_of_type_char*
before you did
a[0][0] = aChar;

For instance, in this particular code segment, you could do
a[0] = malloc( 4 );

> Now the above only works if I add nothing else to the program, that is-- when i try this with reading lines of text from a file all hell breaks loose.
Yup, C will let you walk into a minefield, but won't necessarily blow you up at the first problem.
• 11-09-2008
itCbitC
Quote:

Originally Posted by tlpog
#2. *(a + 0) + 0..... Now take what a[0] points to, which is the starting address of the first char array, and deference the value, which should now give me the starting address of the single character at the beginning of the char array. Thus *(a + 0) + 1 should be the address of the second member of the char array and so on

*(a + 0) + 1 adds 1 to whatever a[0] is pointing to; eg if a[0] points to the string "hello world" then *(a + 0) + 1 adds 1 to 'h' giving you the character 'i' which is not an lvalue. So *(a + 0) + 1 is not the address of the second member of the char array but (a + 0) + 1 is actually a[1].
Ofcourse I'm assuming that you are on a machine with an ASCII character set not EBCDIC.
• 11-09-2008
tlpog
thanks for the quick reply salem.. I definately suspected something to do with memory allocation... guess it's time for me to learn something new :)
• 11-09-2008
tlpog
If i understand your comment itCbitC, you are saying *(a + 0) + 1 adds 1 to ASCI of 'h', which of course returns a junk value. Maybe I need a clarification of what this decleration : char *a[3]; ... really means. Now from my understanding a contains 3 members each a pointer. Each pointer points to the starting address of the char array. So by saying *(a + 0) + 1 I am saying add 0 to the top level, deference that value... so now we get the address of the char array and NOT the ASCI value which means i can continue with the pointer arithmetic? So saying *(a + 0) returns the base adress while *(a + 0) + 3 returns the base adress + 3... Did what i just say complete B.S?
• 11-09-2008
itCbitC
Quote:

Originally Posted by tlpog
If i understand your comment itCbitC, you are saying *(a + 0) + 1 adds 1 to ASCI of 'h', which of course returns a junk value. Maybe I need a clarification of what this decleration : char *a[3]; ... really means. Now from my understanding a contains 3 members each a pointer.

Yes that is correct.
Quote:

Originally Posted by tlpog
Each pointer points to the starting address of the char array.

Need not be an array of char...could be just one char.
Quote:

Originally Posted by tlpog
So by saying *(a + 0) + 1 I am saying add 0 to the top level, deference that value... so now we get the address of the char array

Yes you are getting the address of the char array by dereferencing it.
If a[0] points to the string "hello" then *a[0] accesses the letter 'h' and *(a +0) + 1 adds one to the contents of a[0].
I apologize if I confused you. I wound myself into knots too. Well that's what happens when one multitasks. :confused:
• 11-09-2008
tlpog
I screwed some based on your suggestions ItsC...

Code:

```char *a[3] = {"AEI", "OUY", "JKL"};         printf("OUTPUT 1: &#37;c\n", *a[0]); //Accesses the letter A         printf("OUTPUT 2: %c\n", *(a[0] + 1)); // Accesses a the string and adds 1         // then deferences it         printf("OUTPUT 3: %c\n", *(a[0] + 2)); // and again                 //But...         (*a[0]) = 'p';         printf("OUTPUT 4: %c\n", *a[0]); // doesn't work... i don't get output```
OUTPUT 1: A
OUTPUT 2: E
OUTPUT 3: I

Does it mean the strings in a[3] are const? Since now i definately know there is memory allocated for the *a[0] spot.

So based on the most recent comment...

Code:

```*(*(a + 0) + 0) = 'p';         printf("OUTPUT 4: %c\n", *a[0]);```
still no dice... i am trying to say- #1. Take the array of a and add 0 to it so we get a[0] #2 defference that so we get the adresse of *a[0] #3 add 0 to that so we are point at the first element of *a[0] or the first element of the string AEI which is A #4 deference that value again so now we get the ASCI of A... which I assume if the type is not constant i can assign 'p' to
• 11-09-2008
itCbitC
Quote:

Originally Posted by tlpog
I screwed some based on your suggestions ItsC...

I apologize as I got somewhat mixed up with this roundabout way of initializing array elements.
Quote:

Originally Posted by tlpog
Code:

```char *a[3] = {"AEI", "OUY", "JKL"};         printf("OUTPUT 1: %c\n", *a[0]); //Accesses the letter A         printf("OUTPUT 2: %c\n", *(a[0] + 1)); // Accesses a the string and adds 1         // then deferences it         printf("OUTPUT 3: %c\n", *(a[0] + 2)); // and again```

This walks along the first string "AEI" and that's why the output 'E' is as expected. To print the letter B add 1 to A as in *a[0] + 1.
Quote:

Originally Posted by tlpog
//But...
(*a[0]) = 'p';
printf("OUTPUT 4: %c\n", *a[0]); // doesn't work... i don't get output[/CODE]

Can't do this because it's of the type const char.
Quote:

Originally Posted by tlpog
OUTPUT 1: A
OUTPUT 2: E
OUTPUT 3: I

Does it mean the strings in a[3] are const? Since now i definately know there is memory allocated for the *a[0] spot.

Yes the strings in a[3] are const and sure enough there is memory allocated for storing each of those strings.
• 11-09-2008
tlpog
Thank you salem and itC for the comments... I think I have enough info now to correct the problem. If i declare something like *a[3]; without initializing the variable with const data and later allocating memory to the arrays i should be able to modify each element of *a[i] with whatever data i choose :)
• 11-09-2008
itCbitC
Quote:

Originally Posted by tlpog
Thank you salem and itC for the comments... I think I have enough info now to correct the problem. If i declare something like *a[3]; without initializing the variable with const data and later allocating memory to the arrays i should be able to modify each element of *a[i] with whatever data i choose :)

Yes that approach lets you modify *a[i].
• 11-09-2008
itCbitC
Quote:

Originally Posted by tlpog
Code:

```*(*(a + 0) + 0) = 'p';         printf("OUTPUT 4: %c\n", *a[0]);```
still no dice... i am trying to say- #1. Take the array of a and add 0 to it so we get a[0] #2 defference that so we get the adresse of *a[0] #3 add 0 to that so we are point at the first element of *a[0] or the first element of the string AEI which is A #4 deference that value again so now we get the ASCI of A... which I assume if the type is not constant i can assign 'p' to

imho by stepwise dissecting the expression *(*(a + 0) + 0) as in
a + 0 is a pointer to the first element of a ie a + 0 == &a[0].
*(a + 0) applies dereferencing to obtain a[0].
*(a + 0) + 0 points to the same place that a[0] is pointing to.
*(*(a + 0) + 0) accesses the object that a[0] is pointing to ie 'A' in this case.
• 11-09-2008
tabstop
Quote:

Originally Posted by itCbitC
imho by stepwise dissecting the expression *(*(a + 0) + 0) as in
a + 0 is a pointer to the first element of a ie a + 0 == &a[0].
*(a + 0) applies dereferencing to obtain a[0].
*(a + 0) + 0 points to the same place that a[0] is pointing to.

We were doing fine up to right here. *(a+0) is a character a[0], adding 0 to it gives us the same character.
Quote:

Originally Posted by itCbitC
*(*(a + 0) + 0) accesses the object that a[0] is pointing to ie 'A' in this case.

And this is just an error.
• 11-09-2008
itCbitC
Quote:

Originally Posted by tabstop
We were doing fine up to right here. *(a+0) is a character a[0], adding 0 to it gives us the same character.

And this is just an error.

care to explain if you please what you mean by the above statement??
• 11-09-2008
tabstop
Quote:

Originally Posted by itCbitC
care to explain if you please what you mean by the above statement??

What it means is that I can't read. We have an array of char *, not of char as I had originally read it. So yes what you said is what we have. Sorry.
• 11-09-2008
itCbitC