473,419 Members | 1,683 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,419 software developers and data experts.

pointer-to-pointer to char

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
22 2590
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
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
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
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
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
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
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
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
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
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
"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
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
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
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
"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
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

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
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

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
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

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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Yang Song | last post by:
HI, I am a little confused about char * and char. How would I be able to return a char* created in a function? Is new() the only way? How would I be able to return a point and a value at the same...
9
by: Christopher Benson-Manica | last post by:
I need a smart char * class, that acts like a char * in all cases, but lets you do some std::string-type stuff with it. (Please don't say to use std::string - it's not an option...). This is my...
5
by: Brad Moore | last post by:
Hey all, I'm getting the following compiler error from my code. I was wondering if anyone could help me understand the concept behind it (I actually did try and compile this degenerate...
5
by: Alex Vinokur | last post by:
"Richard Bos" <rlb@hoekstra-uitgeverij.nl> wrote in message news:4180f756.197032434@news.individual.net... to news:comp.lang.c > ben19777@hotmail.com (Ben) wrote: > > 2) Structure casted into an...
5
by: Sona | last post by:
I understand the problem I'm having but am not sure how to fix it. My code passes two char* to a function which reads in some strings from a file and copies the contents into the two char*s. Now...
2
by: Peter Nilsson | last post by:
In a post regarding toupper(), Richard Heathfield once asked me to think about what the conversion of a char to unsigned char would mean, and whether it was sensible to actually do so. And pete has...
5
by: jab3 | last post by:
(again :)) Hello everyone. I'll ask this even at risk of being accused of not researching adequately. My question (before longer reasoning) is: How does declaring (or defining, whatever) a...
12
by: GRoll35 | last post by:
I get 4 of those errors. in the same spot. I'll show my parent class, child class, and my driver. All that is suppose to happen is the user enters data and it uses parent/child class to display...
4
by: Paul Brettschneider | last post by:
Hello all, consider the following code: typedef char T; class test { T *data; public: void f(T, T, T); void f2(T, T, T);
29
by: Kenzogio | last post by:
Hi, I have a struct "allmsg" and him member : unsigned char card_number; //16 allmsg.card_number
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.