What is wrong with this: *p++=*s++

M

Matt

Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt
 
M

Mark A. Odell

(e-mail address removed) (Matt) wrote in

I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.

Of course. p and s point to non-modifiable memory. On embedded systems
these *constant* strings might be in FLASH memory. Clearly you don't
expect to be able to modify FLASH memory with a simple write? No, nor may
you attempt to modify string literals on any system. You should learn to
define p and s correctly as:

const char *p = "Hello";
const char *s = "World";

Then you will get the correct compile time error instead of a run-time
error.
 
E

Eric Sosman

Matt said:
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?

This is Question 16.6 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
 
P

Peter Nilsson

Eric Sosman said:
Matt said:
Hi,

I have a probelm here:

If I declare:

char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?

This is Question 16.6 in the comp.lang.c

As that 16.6 states, it's covered even earlier in 1.32.
 
M

Matt

Thanks guy for the help.


One more question:
Do we have any function in C to delete a substring in a string. I
know C++ does but what about C?


Matt


Peter Nilsson said:
Eric Sosman said:
Matt said:
Hi,

I have a probelm here:

If I declare:

char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?

This is Question 16.6 in the comp.lang.c

As that 16.6 states, it's covered even earlier in 1.32.
Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
 
A

Arthur J. O'Dwyer

One more question:
Do we have any function in C to delete a substring in a string. I
know C++ does but what about C?

Please remember to snip any quotes not relevant to your post
(which in this case was everything, which means you ought to have
started a new thread with a nice descriptive subject line).

No. You can, however, use 'memmove' (NOT 'memcpy' or 'strcpy',
though), like this:

char buffer[1000] = "foobarbaz";
char remove[] = "bar";

char *find_it = strstr(buffer, remove);
if (find_it != NULL) {
/*
The substring exists in the buffer.
Erase it by copying the rest of the string
over top of it. Note that we are copying
the length of the remaining string /plus one/,
so that we copy the terminating null character.

Note also that this comment is needlessly verbose,
for pedagogical reasons. :)
*/
memmove(find_it,
find_it+strlen(remove),
strlen(find_it)-strlen(remove)+1
);
}
puts(buffer);

HTH,
-Arthur
 
M

Matt

Thanks Arthur,

Wow, It was a very smart code. I learned a lot from you. I really appreciate.


Matt


Arthur J. O'Dwyer said:
One more question:
Do we have any function in C to delete a substring in a string. I
know C++ does but what about C?

Please remember to snip any quotes not relevant to your post
(which in this case was everything, which means you ought to have
started a new thread with a nice descriptive subject line).

No. You can, however, use 'memmove' (NOT 'memcpy' or 'strcpy',
though), like this:

char buffer[1000] = "foobarbaz";
char remove[] = "bar";

char *find_it = strstr(buffer, remove);
if (find_it != NULL) {
/*
The substring exists in the buffer.
Erase it by copying the rest of the string
over top of it. Note that we are copying
the length of the remaining string /plus one/,
so that we copy the terminating null character.

Note also that this comment is needlessly verbose,
for pedagogical reasons. :)
*/
memmove(find_it,
find_it+strlen(remove),
strlen(find_it)-strlen(remove)+1
);
}
puts(buffer);

HTH,
-Arthur
 
D

Dan Pop

In said:
One more question:
Do we have any function in C to delete a substring in a string.

No, because it is not needed often enough and anyone with half a clue
can put strstr and memmove together to get the job done. Just be
careful when computing the number of bytes to be moved.

Dan
 
H

hugo27

Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt

hugo27 July 24, 2004
What is Matt's intent? To concat the two strings? Or to alter *p?
And what does *p++=*s++; actually do?

I know from my own investigations that a construct such as *p++
first increments the address in p (by 1, because char type).
This makes *p point to the 'e' in "Hello". Then it fetches the
the object, 'e', or makes it available. The 'H' is still there
in the string. It's as if *p++ moves the "start maker" of the
string.

Likewise, *s++ makes *s point at the 'o' in "world", and
fetches the code for 'o'.
Then the = executes. What happens? The program tries to insert
the code for 'o' on top of the code for 'e'. The 'e' is not a
variable, so a memory (segment) error results.

hugo.
 
B

Barry Schwarz

[email protected] (Matt) wrote in message news: said:
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt

hugo27 July 24, 2004
What is Matt's intent? To concat the two strings? Or to alter *p?
And what does *p++=*s++; actually do?

I know from my own investigations that a construct such as *p++
first increments the address in p (by 1, because char type).

Then you need to investigate further. While it is true that the ++
post increment operator will increment p, you have no idea when this
side-effect will actually occur other than sometime before the next
sequence point. Therefore, it is incorrect to assume it will occur
first.
This makes *p point to the 'e' in "Hello". Then it fetches the

While it is true that after p is incremented it points to the 'e',
this has absolutely no affect on the value returned by the expression
since the post increment operator expression will always evaluate to
the pre-incremented value of the operand. Therefore, the first time
the statement is executed would result in the 'H' being replaced
(except for the fact that the 'H' is part of a string literal and any
attempt to modify it results in undefined behavior).
the object, 'e', or makes it available. The 'H' is still there
Nope.

in the string. It's as if *p++ moves the "start maker" of the
string.

It is as if *p++ causes the character currently pointed to by p to be
replaced and then increments p.
Likewise, *s++ makes *s point at the 'o' in "world", and
fetches the code for 'o'.

Wrong for exactly the same reason.
Then the = executes. What happens? The program tries to insert
the code for 'o' on top of the code for 'e'. The 'e' is not a
variable, so a memory (segment) error results.

'e' is never a variable. As far as undefined behavior goes, a memory
is actually one of the more fortuitous manifestations.


<<Remove the del for email>>
 
K

Kurt Watzka

hugo27 said:
(e-mail address removed) (Matt) wrote in message
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt

hugo27 July 24, 2004
What is Matt's intent? To concat the two strings? Or to alter *p?
And what does *p++=*s++; actually do?

I know from my own investigations that a construct such as *p++
first increments the address in p (by 1, because char type).

No, it doesn't. The effect ist identical to

*p = *s; p = p + 1; s = s + 1;

or

*p = *s; s = s + 1; p = p + 1;

This makes *p point to the 'e' in "Hello". Then it fetches the
the object, 'e', or makes it available. The 'H' is still there
in the string. It's as if *p++ moves the "start maker" of the
string.

Likewise, *s++ makes *s point at the 'o' in "world", and
fetches the code for 'o'.
Then the = executes. What happens? The program tries to insert
the code for 'o' on top of the code for 'e'. The 'e' is not a
variable, so a memory (segment) error results.

You're right in principle, but wrong in the details. "*p++ = *s++"
tries to move the 'w' to the place where the 'H' is stored,
not the 'o' to the place where the 'e' is stored. Since both
the place where the 'H' is stored and the place where the 'e'
is stored need not be writable memory locations, an error
may occur.

Kurt Watzka
 
H

Hamed

Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.
Sincerely,
Hamed
 
M

Matt

How you can do this? As far as I know, you are assigning a string to a
character. It is not compatible.

Matt


Hamed said:
Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.
Sincerely,
Hamed

Matt said:
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt
 
B

Barry Schwarz

How you can do this? As far as I know, you are assigning a string to a
character. It is not compatible.

p is not a char. It is an array of char. And a definition of the
form
char p[80] = "Hello";
will work quite nicely.
Matt


Hamed said:
Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.
Sincerely,
Hamed

Matt said:
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt



<<Remove the del for email>>
 
Z

zhiwei wang

The difference between the declarations "char *str_pointer" and "char
str_array[80]" is that str_pointer points to a random address unless
you allocate memory before assign it a value and str_array has already
allocate memory when you declare it.
Therefore, if you want to use str_pointer, you need to allocate memory
for it by using functions like "malloc". (and of cource, free the
memroy after you use it.)








How you can do this? As far as I know, you are assigning a string to a
character. It is not compatible.

Matt


Hamed said:
Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.
Sincerely,
Hamed

Matt said:
Hi,


I have a probelm here:

If I declare:


char *p="Hello";

char *s="world"

and I say

*p++=*s++;

I get a segmentation fault. But when I use arrays( say p[80], s[80])
instead of pointers *p and *s every thing is fine.
Can someone tell me what is wrong here?


Regards,
Matt
 
J

Jens.Toerring

Hamed said:
Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.

That's no puzzle at all.

char p[ 80 ];

gives you an array of 80 chars. And you can't change 'p' afterwards
anymore. But that's what you're trying to do when you write

p = "Hello";

because you're treating 'p' as if it where an char pointer by trying
to assign it the address of where the (6 char long) string "Hello" is
stored (possibly in read-only memory). But 'p' isn't a char pointer,
it is an array of chars. And since these are different types the
compiler won't accept that broken code.

You might be a bit confused because when you pass 'p' to a function
what the function actually gets is a pointer to the first element of
the array 'p' (instead of a copy of the array). But that is something
special about _function calls_ with array arguments and does not
change the fact that 'p' is an array which can't be converted to a
pointer here.

And the problem of the Matt has been already explained to him, strings
like the one assigned here to 's'

char *s = "Hello";

are strings that simply can't be changed but that's what he was
trying to do, violating the rules of the game (unfortunately,
there are some implementations that let you get away with this,
making learning this more difficult).
Regards, Jens
 
H

Hamed

Hi Jens,
You didn't read my comments in its entirety. All I was trying to explain to
him was that when he does
char p[80] = "Hello"; He copies the chars to the array's allocated memory.
When he does char * p ="Hello"; he points to a read-only memory without
copying anything. By giving him the example, I was trying to tell him that
arrays are not pointers. Arrays and pointers are like orange and apple that
share some characteristics.
Sincerely,
Hamed

Hamed said:
Hi Matt,
If you want to add mystery to your puzzle try this:
char p [80];
char s [80];
p = "Hello";
s = "world";
Now it won't even compile. ;-) Let me know if this hint helps you figure out
what the problem is with your code.

That's no puzzle at all.

char p[ 80 ];

gives you an array of 80 chars. And you can't change 'p' afterwards
anymore. But that's what you're trying to do when you write

p = "Hello";

because you're treating 'p' as if it where an char pointer by trying
to assign it the address of where the (6 char long) string "Hello" is
stored (possibly in read-only memory). But 'p' isn't a char pointer,
it is an array of chars. And since these are different types the
compiler won't accept that broken code.

You might be a bit confused because when you pass 'p' to a function
what the function actually gets is a pointer to the first element of
the array 'p' (instead of a copy of the array). But that is something
special about _function calls_ with array arguments and does not
change the fact that 'p' is an array which can't be converted to a
pointer here.

And the problem of the Matt has been already explained to him, strings
like the one assigned here to 's'

char *s = "Hello";

are strings that simply can't be changed but that's what he was
trying to do, violating the rules of the game (unfortunately,
there are some implementations that let you get away with this,
making learning this more difficult).
Regards, Jens
 
S

Strix Nihildom

*p++=*s++

when you do stuff like this use parentheses because (++) and (*) are
associative from right to left and have equal precedence however if for some
reason you want it to read *(p++)= (*s++) it creates a different result...
 
B

Ben Pfaff

when you do stuff like this use parentheses

I disagree. This statement is idiomatic. Every C programmer
should understand what it means.
[...] if for some reason you want it to read *(p++)= (*s++) it
creates a different result...

No, those two expressions are equivalent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,372
Latest member
LucretiaFo

Latest Threads

Top