By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,291 Members | 3,120 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,291 IT Pros & Developers. It's quick & easy.

pointer-to-pointer to char

P: n/a
The following code can be compiled. But When I run it, it causes
"Segmentation fault".

int main(){
char **c1;

*c1 = "HOW"; // LINE1

++(*c1);
*c1 = "ARE";

++(*c1);
*c1 = "YOU";
}

c1 is a pointer-to-pointer to char. How to initialize c1 to three
strings: "HOW", "ARE", "YOU"?

Thanks a lot.

May 28 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Jack wrote:
The following code can be compiled. But When I run it, it causes
"Segmentation fault".

int main(){
char **c1;

*c1 = "HOW"; // LINE1
c1 doesn't point to anything...
c1 is a pointer-to-pointer to char. How to initialize c1 to three
strings: "HOW", "ARE", "YOU"?

char *c1[] = { "HOW", "ARE", "YOU" };

--
Ian Collins.
May 28 '06 #2

P: n/a
Ian Collins wrote:
Jack wrote:
The following code can be compiled. But When I run it, it causes
"Segmentation fault".

int main(){
char **c1;

*c1 = "HOW"; // LINE1


c1 doesn't point to anything...
c1 is a pointer-to-pointer to char. How to initialize c1 to three
strings: "HOW", "ARE", "YOU"?


char *c1[] = { "HOW", "ARE", "YOU" };

I should have said

const char *c1[] = { "HOW", "ARE", "YOU" };

--
Ian Collins.
May 28 '06 #3

P: n/a
Jack wrote:
The following code can be compiled. But When I run it, it causes
"Segmentation fault".

int main(){
char **c1;

*c1 = "HOW"; // LINE1
Boom! Crash and burn! c1 is not initialized and *c1 is garbage.
++(*c1);
*c1 = "ARE";

++(*c1);
*c1 = "YOU";
}

c1 is a pointer-to-pointer to char. How to initialize c1 to three
strings: "HOW", "ARE", "YOU"?

Thanks a lot.

#include <stdlib.h>

char **c1 = malloc(3 * sizeof *c1);
c1[0] = "HOW";
c1[1] = "ARE";
c1[2] = "YOU";

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
May 28 '06 #4

P: n/a
char **c1;

*c1 = "HOW";

Most (if not all) novices make this mistake at some stage, but it doesn't
take long before you can spot it from a mile away. Here's a sample:

char *p;

The variable "p" stores a memory address (at which resides a char). You
didn't initialise it, so it contains white noise. Let's say its value is:
8374534.

*p = 'a';
Now you dereference this pointer value, and write to the memory. So
you're writing 'a' to the memory location: 8374534.

You have to give "p" a legitimate value:

char k;

char *p = &k;
Let's say that k is stored at the memory address: 234873. Now p is
storing the value: 234873. This is a legitimate memory location to
access:

*p = 'e';
The crux of the matter is this: When you define a pointer variable,
you're DON'T actually allocate memory for the variable which it points
to. But it's easist to think along the following lines: A "char*" stores
a memory address.
-Tomás
May 28 '06 #5

P: n/a
Tomás wrote:
char **c1;

*c1 = "HOW";

Most (if not all) novices make this mistake at some stage, but it doesn't
take long before you can spot it from a mile away. Here's a sample:

char *p;

The variable "p" stores a memory address (at which resides a char). You
didn't initialise it, so it contains white noise. Let's say its value is:
8374534.

*p = 'a';


The value of an unitialized pointer is of no interest. The above
statement is undefined behavior and may cause segment fault or other error.

Now you dereference this pointer value, and write to the memory. So
you're writing 'a' to the memory location: 8374534.
Please see my comment above.
You have to give "p" a legitimate value:

char k;

char *p = &k;
That's better. p holds the address of k and k is sufficient to hold 'e'.
Let's say that k is stored at the memory address: 234873. Now p is
storing the value: 234873. This is a legitimate memory location to
access:
Again, the actual value of a pointer is of no interest.
*p = 'e';
This works and now (k == 'e') is true.
The crux of the matter is this: When you define a pointer variable,
you're DON'T actually allocate memory for the variable which it points
to. But it's easist to think along the following lines: A "char*" stores
a memory address.
More correctly, an object of type char* may contain the address of an
object of type char.
-Tomás

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
May 28 '06 #6

P: n/a
Joe Wright posted:

The variable "p" stores a memory address (at which resides a char).
You didn't initialise it, so it contains white noise. Let's say its
value is: 8374534.

*p = 'a';
The value of an unitialized pointer is of no interest.

It is for the purpose of my tutorial -- it gives the original poster a
concrete, down-to-earth example of what's going on. When you don't
initialise a variable, it sort of has a random value (which may not even
be a valid bit-pattern for the given type).

The above
statement is undefined behavior and may cause segment fault or other
error.

Congratulations, you understand.

That's better. p holds the address of k and k is sufficient to hold
'e'.

Should I presume that the remainder of your post simply repeats every
point I made in my previous post?

This works and now (k == 'e') is true.

An inaccurate method of testing. I bet you I could get the following to
work on my system:

char *p;

*p = 'e';

if ( *p == 'e' ) NaivelyIndicateSuccess();

The crux of the matter is this: When you define a pointer variable,
you're DON'T actually allocate memory for the variable which it
points to. But it's easist to think along the following lines: A
"char*" stores a memory address.

More correctly, an object of type char* may contain the address of an
object of type char.

(Maybe I'm getting mixed up with C and C++ here, but in C++, you can use
a char* to access ANY memory. Would you have to use an unsigned char* in
C?)
-Tomás
May 28 '06 #7

P: n/a
Tomás wrote:
Joe Wright posted:

The variable "p" stores a memory address (at which resides a char).
You didn't initialise it, so it contains white noise. Let's say its
value is: 8374534.

*p = 'a'; The value of an unitialized pointer is of no interest.

It is for the purpose of my tutorial -- it gives the original poster a
concrete, down-to-earth example of what's going on. When you don't
initialise a variable, it sort of has a random value (which may not even
be a valid bit-pattern for the given type).

The above
statement is undefined behavior and may cause segment fault or other
error.

Congratulations, you understand.

That's better. p holds the address of k and k is sufficient to hold
'e'.

Should I presume that the remainder of your post simply repeats every
point I made in my previous post?

This works and now (k == 'e') is true.

An inaccurate method of testing. I bet you I could get the following to
work on my system:

char *p;

*p = 'e';

if ( *p == 'e' ) NaivelyIndicateSuccess();

But we agree that this is undefined, don't we?
The crux of the matter is this: When you define a pointer variable,
you're DON'T actually allocate memory for the variable which it
points to. But it's easist to think along the following lines: A
"char*" stores a memory address.
More correctly, an object of type char* may contain the address of an
object of type char.

(Maybe I'm getting mixed up with C and C++ here, but in C++, you can use
a char* to access ANY memory. Would you have to use an unsigned char* in
C?)

Yes, 'unsigned char*' is the method to access any byte in memory in C.
Since C89 we have 'void*' to hold any memory address but it can't be
used to access memory directly.
-Tomás

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
May 28 '06 #8

P: n/a
Joe Wright posted:

char *p;

*p = 'e';

if ( *p == 'e' ) NaivelyIndicateSuccess();

But we agree that this is undefined, don't we?

Yes of course. (I didn't want to state the obvious).
-Tomás
May 28 '06 #9

P: n/a
Thanks a lot.
But why the following code works well?
int *p;
*p = 5;

Moreover, I find that many textbooks use the following code to
initialize a char pointer:
char *c;
c = "test";

Is it wrong?

Thanks.

May 28 '06 #10

P: n/a
Jack posted:
Thanks a lot.
But why the following code works well?
int *p;
*p = 5;

Learn to be more articulate when asking questions.
Question: Why does it compile?

Answer: Because there's nothing in the Standard which it must not
compile.
Question: When I run the executable, why does it run normally without
error?

Answer: Because you're luck (or unlucky). Your system simply isn't
complaining about you accessing memory which isn't yours to access. If
you've got a Disk Format Program running at the same time, you may alter
its boolean value which determines whether it should format the C drive.

Moreover, I find that many textbooks use the following code to
initialize a char pointer:
char *c;
c = "test";

Stupid, but not wrong. I'm too lazy to explain why though. Go to:

http://www.possibility.com/Cpp/const.html

and do a text search for "undefined, modifying static buffer!!!"
-Tomás
May 28 '06 #11

P: n/a
"Jack" <ju******@gmail.com> writes:
But why the following code works well?
int *p;
*p = 5;
There's always the chance that an uninitialized pointer happens
to point to memory that, when modified, doesn't exhibit any
immediately bad behavior. That's bad: it means that the error
doesn't show up in testing, or perhaps that it makes the error
look like it's in some unrelated part of your program.
Moreover, I find that many textbooks use the following code to
initialize a char pointer:
char *c;
c = "test";

Is it wrong?


No, this is correct code[*]. The difference here is that this
statement sets the value `c'. The former code does not set the
value of `c'; rather, it *uses* the (uninitialized) value of `c',
by dereferencing it.
[*] Although it would be better to declare `c' as type `const
char *', because literal strings are non-modifiable.
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton
May 28 '06 #12

P: n/a
What is the problem with the following code?

int **p1;
int a1[] = {2,3,4};
int a2[] = {22,33};
int a3[] = {22,33,44,55};

int *b1, *b2, *b3;

b1 = a1;
b2 = a2;
b3 = a3;

p1 = &b1;
p1++;
p1=&b2;
p1++;
p1=&b3;

p1 = p1-2;

for(int i = 0; i < 3; i++){
std::cout <<"*((*p1)+"<<i<<"): "<< *((*p1)+i)<<std::endl; //LINE1
}

p1++;
for(int i = 0; i < 2; i++){
std::cout <<"*(*(p1+1)+"<<i<<"): "<< *(*(p1)+i)<<std::endl; //LINE2
}
LINE1 prints unexpected numbers. LINE2 causes "Segmentation fault".
Why?

Thanks.

May 29 '06 #13

P: n/a
Jack posted:

int **p1;

OK.

int a1[] = {2,3,4};

OK.

int a2[] = {22,33};

OK.

int a3[] = {22,33,44,55};

OK.


int *b1, *b2, *b3;

OK.

b1 = a1;
b2 = a2;
b3 = a3;

OK.

p1 = &b1;

OK.

p1++;

p1 now contains garbage.

p1=&b2;

OK.

p1++;

p1 now contains garbage.

p1=&b3;

OK.

p1 = p1-2;

p1 now contain garbage.

LINE1 prints unexpected numbers. LINE2 causes "Segmentation fault".
Why?

Your code makes the unfounded presumption that b1, b2, and b3 are
contiguous in memory. What you want is something like:

int *array_pointers[3];

#define b1 (*array_pointers)
#define b2 (array_pointers[1])
#define b3 (array_pointers[2])
Here's the revised code:

int main(void)
{

int **p1;
int a1[] = {2,3,4};
int a2[] = {22,33};
int a3[] = {22,33,44,55};

int *array_pointers[3];

#define b1 (*array_pointers)
#define b2 (array_pointers[1])
#define b3 (array_pointers[2])

b1 = a1;
b2 = a2;
b3 = a3;

p1 = &b1;
p1++;
p1=&b2;
p1++;
p1=&b3;

p1 = p1-2;
}
As for using C standard output rather than C++ standard output... I'll
leave that one up to you.

-Tomás

May 29 '06 #14

P: n/a
Thanks a lot. I tested your code. It works well!
Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
contiguous in memory?
My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
even if b1, b2 and b3 in my code are not contiguous in memory, I can
still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?

To make it easy to read, part of my code is below:

int **p1;
int a1[] = {2,3,4};
int a2[] = {22,33};
int a3[] = {22,33,44,55};

int *b1, *b2, *b3;

b1 = a1;
b2 = a2;
b3 = a3;

p1 = &b1;
p1++;
p1=&b2;
p1++;
p1=&b3;

p1 = p1-2;
Thanks.

May 29 '06 #15

P: n/a
"Jack" <ju******@gmail.com> writes:
What is the problem with the following code?

int **p1; [snip] for(int i = 0; i < 3; i++){
std::cout <<"*((*p1)+"<<i<<"): "<< *((*p1)+i)<<std::endl; //LINE1
}

[snip]

There are at least two major problems.

1. It's not a complete program, though you could easily have made it
one (which would have made it easier for us to help).

2. It's not C, it's C++.

Please take the time to post a complete, self-contained program.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
May 29 '06 #16

P: n/a
On 2006-05-29, Jack <ju******@gmail.com> wrote:
Thanks a lot. I tested your code. It works well!
Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
contiguous in memory?
My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
even if b1, b2 and b3 in my code are not contiguous in memory, I can
still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
p1+1 points to the memory location immediately after the original p1.
Here's a small diagram to help:

--------------------
| p1 | p1+1 | p1+2 |
--------------------
| | |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

That is a very artificial example, as b1, b2, and b3 could be
millions of bytes away from each other! However, p1+1 will always
point to the place after p1.

To make it easy to read, part of my code is below:

int **p1;
int a1[] = {2,3,4};
int a2[] = {22,33};
int a3[] = {22,33,44,55};

int *b1, *b2, *b3;

b1 = a1;
b2 = a2;
b3 = a3;

p1 = &b1;
p1++;
p1=&b2;
p1++;
p1=&b3;

p1 = p1-2;

I've left that for people to comment.
--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
It's just like stealing teeth from a baby.
May 29 '06 #17

P: n/a

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:
Thanks a lot. I tested your code. It works well!
Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
contiguous in memory?
My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
even if b1, b2 and b3 in my code are not contiguous in memory, I can
still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
p1+1 points to the memory location immediately after the original p1.
Here's a small diagram to help:

--------------------
| p1 | p1+1 | p1+2 |
--------------------
| | |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

That is a very artificial example, as b1, b2, and b3 could be
millions of bytes away from each other! However, p1+1 will always
point to the place after p1.


Do you mean that the memory that p1, (p1+1) and (p1+2) point to must be
contiguous?
p1, (p1+1) and (p1+2) are contiguous. b1's address is stored in p1,
b2's address is stored in (p1+1), and b3's address is stored in (p1+2).
Why b1, b2, and b3 must be contiguous? Thanks.

Jack


To make it easy to read, part of my code is below:

int **p1;
int a1[] = {2,3,4};
int a2[] = {22,33};
int a3[] = {22,33,44,55};

int *b1, *b2, *b3;

b1 = a1;
b2 = a2;
b3 = a3;

p1 = &b1;
p1++;
p1=&b2;
p1++;
p1=&b3;

p1 = p1-2;

I've left that for people to comment.
--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
It's just like stealing teeth from a baby.


May 29 '06 #18

P: n/a
On 2006-05-29, Jack <ju******@gmail.com> wrote:

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:
> Thanks a lot. I tested your code. It works well!
> Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
> contiguous in memory?
> My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
> even if b1, b2 and b3 in my code are not contiguous in memory, I can
> still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
>

p1+1 points to the memory location immediately after the original p1.
Here's a small diagram to help:

--------------------
| p1 | p1+1 | p1+2 |
--------------------
| | |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

That is a very artificial example, as b1, b2, and b3 could be
millions of bytes away from each other! However, p1+1 will always
point to the place after p1.


Do you mean that the memory that p1, (p1+1) and (p1+2) point to must be
contiguous?
p1, (p1+1) and (p1+2) are contiguous. b1's address is stored in p1,
b2's address is stored in (p1+1), and b3's address is stored in (p1+2).
Why b1, b2, and b3 must be contiguous? Thanks.

If b1's address is stored in p1, you have double indirection. I'm not
sure that that is what you mean or want, but here's an expaination:

---------------------------
| p1 | p1+1 | p1+2 |
---------------------------
| | |
---------------------------
| *p1 | *(p1+1) | *(p1+2) |
---------------------------
| | \-----------\
| | |
| \-------------\ |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

In this case, *p1, *(p1+1), and *(p1+2) are all pointers in themselves.
I recommend you avoid double indirection until you have a firm grasp
on other aspects of pointers.
May 29 '06 #19

P: n/a

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:
> Thanks a lot. I tested your code. It works well!
> Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
> contiguous in memory?
> My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
> even if b1, b2 and b3 in my code are not contiguous in memory, I can
> still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
>
p1+1 points to the memory location immediately after the original p1.
Here's a small diagram to help:

--------------------
| p1 | p1+1 | p1+2 |
--------------------
| | |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

That is a very artificial example, as b1, b2, and b3 could be
millions of bytes away from each other! However, p1+1 will always
point to the place after p1.


Do you mean that the memory that p1, (p1+1) and (p1+2) point to must be
contiguous?
p1, (p1+1) and (p1+2) are contiguous. b1's address is stored in p1,
b2's address is stored in (p1+1), and b3's address is stored in (p1+2).
Why b1, b2, and b3 must be contiguous? Thanks.

If b1's address is stored in p1, you have double indirection. I'm not
sure that that is what you mean or want, but here's an expaination:

---------------------------
| p1 | p1+1 | p1+2 |
---------------------------
| | |
---------------------------
| *p1 | *(p1+1) | *(p1+2) |
---------------------------
| | \-----------\
| | |
| \-------------\ |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

In this case, *p1, *(p1+1), and *(p1+2) are all pointers in themselves.
I recommend you avoid double indirection until you have a firm grasp
on other aspects of pointers.


Thank you for your creative figure using text format.
The figure below expresses what I mean. Why it does not work?

------------------------------------
| p1 | p1+1 | p1+2 |
----------------------------------
| | |
| | \--------\
| | |
| \-------------\ |
-------------------------------------
| b1 | ? | ? | b2 | b3 |
-------------------------------------

p1 = &b1;
p1++;
p1 = &b2;
p1++;
p1 = &b3;

p1 = p1-2;

Does p1 point to b1 now? I can not figure out what the problem is.

Thanks a lot.

May 30 '06 #20

P: n/a
On 2006-05-30, Jack <ju******@gmail.com> wrote:

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:
>
> Andrew Poelstra wrote:
>> On 2006-05-29, Jack <ju******@gmail.com> wrote:
>> > Thanks a lot. I tested your code. It works well!
>> > Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
>> > contiguous in memory?
>> > My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
>> > even if b1, b2 and b3 in my code are not contiguous in memory, I can
>> > still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
>> >
>> p1+1 points to the memory location immediately after the original p1.
>> Here's a small diagram to help:
>>
>> --------------------
>> | p1 | p1+1 | p1+2 |
>> --------------------
>> | | |
>> --------------------------------
>> | b1 | ? | ? | b2 | b3 |
>> --------------------------------
>>
>> That is a very artificial example, as b1, b2, and b3 could be
>> millions of bytes away from each other! However, p1+1 will always
>> point to the place after p1.
>
> Do you mean that the memory that p1, (p1+1) and (p1+2) point to must be
> contiguous?
> p1, (p1+1) and (p1+2) are contiguous. b1's address is stored in p1,
> b2's address is stored in (p1+1), and b3's address is stored in (p1+2).
> Why b1, b2, and b3 must be contiguous? Thanks.
> If b1's address is stored in p1, you have double indirection. I'm not
sure that that is what you mean or want, but here's an expaination:

---------------------------
| p1 | p1+1 | p1+2 |
---------------------------
| | |
---------------------------
| *p1 | *(p1+1) | *(p1+2) |
---------------------------
| | \-----\
| | |
| \-----------\ |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

In this case, *p1, *(p1+1), and *(p1+2) are all pointers in themselves.
I recommend you avoid double indirection until you have a firm grasp
on other aspects of pointers.


Thank you for your creative figure using text format.
The figure below expresses what I mean. Why it does not work?

No problem. Note: I fixed minor spacing issues above.
p1 = &b1;
p1++;
p1 = &b2;
p1++;
p1 = &b3;

p1 = p1-2;

Does p1 point to b1 now? I can not figure out what the problem is.

Thanks a lot.

Let's say that &b1 is 1000, &b2 is 1500, and &b3 is 2000.

Here is your code:

p1 = &b1; /* p1 = 1000 */
p1++; /* p1 = 1001 */
p1 = &b2; /* p1 = 1500 */
p1++; /* p1 = 1501 */
p1 = &b3; /* p1 = 2000 */

p1 = p1-2; /* p1 = 1999 */

As you can see, 1999 is not defined in this example, and therefore
when you attempt to dereference it, it is undefined. I'm not sure
what exactly you want the ++'s to do, but that isn't how they work.
--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
You can lead a blind man to water but you can't make him chug it.
May 30 '06 #21

P: n/a

Andrew Poelstra wrote:
On 2006-05-30, Jack <ju******@gmail.com> wrote:

Andrew Poelstra wrote:
On 2006-05-29, Jack <ju******@gmail.com> wrote:
>
> Andrew Poelstra wrote:
>> On 2006-05-29, Jack <ju******@gmail.com> wrote:
>> > Thanks a lot. I tested your code. It works well!
>> > Do you mean that the pointers stored in p1, (p1+1) and (p1+2) must be
>> > contiguous in memory?
>> > My thought is that p1, (p1+1) and (p1+2) are contiguous in memory. So
>> > even if b1, b2 and b3 in my code are not contiguous in memory, I can
>> > still access it through p1, (p1+1) and (p1+2). I must be wrong. Why?
>> >
>> p1+1 points to the memory location immediately after the original p1.
>> Here's a small diagram to help:
>>
>> --------------------
>> | p1 | p1+1 | p1+2 |
>> --------------------
>> | | |
>> --------------------------------
>> | b1 | ? | ? | b2 | b3 |
>> --------------------------------
>>
>> That is a very artificial example, as b1, b2, and b3 could be
>> millions of bytes away from each other! However, p1+1 will always
>> point to the place after p1.
>
> Do you mean that the memory that p1, (p1+1) and (p1+2) point to must be
> contiguous?
> p1, (p1+1) and (p1+2) are contiguous. b1's address is stored in p1,
> b2's address is stored in (p1+1), and b3's address is stored in (p1+2).
> Why b1, b2, and b3 must be contiguous? Thanks.
>
If b1's address is stored in p1, you have double indirection. I'm not
sure that that is what you mean or want, but here's an expaination:

---------------------------
| p1 | p1+1 | p1+2 |
---------------------------
| | |
---------------------------
| *p1 | *(p1+1) | *(p1+2) |
---------------------------
| | \-----\
| | |
| \-----------\ |
--------------------------------
| b1 | ? | ? | b2 | b3 |
--------------------------------

In this case, *p1, *(p1+1), and *(p1+2) are all pointers in themselves.
I recommend you avoid double indirection until you have a firm grasp
on other aspects of pointers.


Thank you for your creative figure using text format.
The figure below expresses what I mean. Why it does not work?

No problem. Note: I fixed minor spacing issues above.
p1 = &b1;
p1++;
p1 = &b2;
p1++;
p1 = &b3;

p1 = p1-2;

Does p1 point to b1 now? I can not figure out what the problem is.

Thanks a lot.

Let's say that &b1 is 1000, &b2 is 1500, and &b3 is 2000.

Here is your code:

p1 = &b1; /* p1 = 1000 */
p1++; /* p1 = 1001 */
p1 = &b2; /* p1 = 1500 */
p1++; /* p1 = 1501 */
p1 = &b3; /* p1 = 2000 */

p1 = p1-2; /* p1 = 1999 */

As you can see, 1999 is not defined in this example, and therefore
when you attempt to dereference it, it is undefined. I'm not sure
what exactly you want the ++'s to do, but that isn't how they work.


Thanks a lot. I understand now.

If I modify my code as below:

int *p1[3];
p1[0] = &b1;
p1[1] = &b2;
p1[2] = &b3;

Now the following figure should work, right?
------------------------------------
| p1 | p1+1 | p1+2 |
----------------------------------
| | |
| | \--------\
| | |
| \-------------\ |
-------------------------------------
| b1 | ? | ? | b2 | b3 |
-------------------------------------

May 30 '06 #22

P: n/a
On 2006-05-30, Jack <ju******@gmail.com> wrote:
Andrew Poelstra wrote:
On 2006-05-30, Jack <ju******@gmail.com> wrote:
> Thank you for your creative figure using text format.
> The figure below expresses what I mean. Why it does not work?
>

No problem. Note: I fixed minor spacing issues above.
> p1 = &b1;
> p1++;
> p1 = &b2;
> p1++;
> p1 = &b3;
>
> p1 = p1-2;
>
> Does p1 point to b1 now? I can not figure out what the problem is.
>
> Thanks a lot.
>

Let's say that &b1 is 1000, &b2 is 1500, and &b3 is 2000.

Here is your code:

p1 = &b1; /* p1 = 1000 */
p1++; /* p1 = 1001 */
p1 = &b2; /* p1 = 1500 */
p1++; /* p1 = 1501 */
p1 = &b3; /* p1 = 2000 */

p1 = p1-2; /* p1 = 1999 */

As you can see, 1999 is not defined in this example, and therefore
when you attempt to dereference it, it is undefined. I'm not sure
what exactly you want the ++'s to do, but that isn't how they work.


Thanks a lot. I understand now.

If I modify my code as below:

int *p1[3];
p1[0] = &b1;
p1[1] = &b2;
p1[2] = &b3;

Now the following figure should work, right?
------------------------------------
| p1 | p1+1 | p1+2 |
----------------------------------
| | |
| | \--------\
| | |
| \-------------\ |
-------------------------------------
| b1 | ? | ? | b2 | b3 |
-------------------------------------


Absolutely! Congratulations on making an array of pointers.

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
You can lead a blind man to water but you can't make him chug it.
May 30 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.