doubt related to string pointers.

J

junky_fellow

what would be the output for the following piece of code ?


if ( "hello" == "hello" )
printf("True\n");
else
printf("False\n");

What is the reason for that ?

-----------------------------------------------------
Secondly, consider the following piece of code.

void main(void)
{
char *str= "hello world";


}
I have seen may C tutorials that say that "str" cannot be
modified. What is the reason for that ? I tried this piece of
code on my machine and I was successfully able to modify it.
 
P

pete

what would be the output for the following piece of code ?

if ( "hello" == "hello" )
printf("True\n");
else
printf("False\n");

Implementation defined.
What is the reason for that ?

Identical string literals may either refer to same
or different objects.
-----------------------------------------------------
Secondly, consider the following piece of code.

void main(void)
{
char *str= "hello world";

}
I have seen may C tutorials that say that "str" cannot be
modified. What is the reason for that ? I tried this piece of
code on my machine and I was successfully able to modify it.

Attempts to modify the string "hello world"
yield undefined behavior, that's bad.
 
M

Michael Mair

Note: a better subject may be "questions about string literals"

what would be the output for the following piece of code ?

if ( "hello" == "hello" )
printf("True\n");
else
printf("False\n");

It depends. You are essentially comparing the address of
the first char of a string literal "hello"(1) with the
address of the first char of a string literal "hello"(2).

If the compiler decided to have them at two separate locations
in memory, the addresses are not equal. If the compiler
throws all string literals which would return 0 when passed
to strcmp() together into a single one, the addresses are
equal.
What is the reason for that ?

The C standard does not specify which of the above has to
hold, so it is essentially arbitrary. If you want to
compare string literals with strings or other string literals,
use strcmp().

Wrong. There is only one main() function in a C program
and it has return type int. From here on, everything
else is pure chance.
{
char *str= "hello world";


}
I have seen may C tutorials that say that "str" cannot be
modified. What is the reason for that ? I tried this piece of
code on my machine and I was successfully able to modify it.

Well, the above piece of code -- even with main() returning
int -- does not modify the string literal.
Be that as it may:
- "hello world" is a string literal.
- string literals have static storage duration, i.e. exist
throughout the whole lifetime of the program
- the C standard says that trying to modify a string literal
invokes undefined behaviour -- so successfully modifying
the literal is definitely one possibility. Unfortunately,
a string literal may be stored in memory which cannot be
modified by your program which in turn could lead to your
program crashing just before giving you the output of some
five million years' worth of computation time... IYKWIM
Bottom line: Do not do it. If you want to modify it, use a
string literal as initialiser for a char array instead.


Cheers
Michael
 
J

junky_fellow

Michael said:
Note: a better subject may be "questions about string literals"



It depends. You are essentially comparing the address of
the first char of a string literal "hello"(1) with the
address of the first char of a string literal "hello"(2).

If the compiler decided to have them at two separate locations
in memory, the addresses are not equal. If the compiler
throws all string literals which would return 0 when passed
to strcmp() together into a single one, the addresses are
equal.


The C standard does not specify which of the above has to
hold, so it is essentially arbitrary. If you want to
compare string literals with strings or other string literals,
use strcmp().

Wrong. There is only one main() function in a C program
and it has return type int. From here on, everything
else is pure chance.


Well, the above piece of code -- even with main() returning
int -- does not modify the string literal.
Be that as it may:
- "hello world" is a string literal.
- string literals have static storage duration, i.e. exist
throughout the whole lifetime of the program
- the C standard says that trying to modify a string literal
invokes undefined behaviour -- so successfully modifying
the literal is definitely one possibility. Unfortunately,
a string literal may be stored in memory which cannot be
modified by your program which in turn could lead to your
program crashing just before giving you the output of some
five million years' worth of computation time... IYKWIM
Bottom line: Do not do it. If you want to modify it, use a
string literal as initialiser for a char array instead.

Thanx for the help Michael. One thing which is not clear is that
why a string literal is stored in non modifiable memory.
What if I don't use any ROM for the execution of my program.
Then can't I modify it ?
 
J

Jens.Toerring

Thanx for the help Michael. One thing which is not clear is that
why a string literal is stored in non modifiable memory.
What if I don't use any ROM for the execution of my program.
Then can't I modify it ?

No. They can be stored wherever the compiler likes to store them.
That could easily by a place in memory you don't have permissions
to write to. They may be stored e.g. in some part of the memory
marked for code only and - to avoid e.g. the program overwriting
it's own code - this part of the memory being marked as read-only.
Moreover the compiler is allowed to concatenate string literals.
E.g. if you have two string literals like

char *a = "hello world";
char *b = "world";

the compiler could make a single string "hello world" out of it,
with 'a' pointing to the start of it and 'b' to the 7th char in
the same literal string. Now, if you would change the literal
string using pointer 'b' you would also change what 'a' is
pointing to - which is definitely not what you would expect.

Regards, Jens
 
M

Michael Mair

Michael said:
Note: a better subject may be "questions about string literals"

(e-mail address removed) wrote: [snip]
Wrong. There is only one main() function in a C program
and it has return type int. From here on, everything
else is pure chance.

{
char *str= "hello world";


}
I have seen may C tutorials that say that "str" cannot be
modified. What is the reason for that ? I tried this piece of
code on my machine and I was successfully able to modify it.

Well, the above piece of code -- even with main() returning
int -- does not modify the string literal.
Be that as it may:
- "hello world" is a string literal.
- string literals have static storage duration, i.e. exist
throughout the whole lifetime of the program
- the C standard says that trying to modify a string literal
invokes undefined behaviour -- so successfully modifying
the literal is definitely one possibility. Unfortunately,
a string literal may be stored in memory which cannot be
modified by your program which in turn could lead to your
program crashing just before giving you the output of some
five million years' worth of computation time... IYKWIM
Bottom line: Do not do it. If you want to modify it, use a
string literal as initialiser for a char array instead.

Thanx for the help Michael. One thing which is not clear is that
why a string literal is stored in non modifiable memory.
What if I don't use any ROM for the execution of my program.
Then can't I modify it ?

The thing is that you could for example write software which
ends up stored in ROM, for example some library routines for
a library which comes with the hardware or the program
governing some chip's behaviour in your
car/washing machine/CD player or just the firmware of some
electronic toy of yours. Alternatively, your system might
provide faster access to memory pages in a read-only mode...
There are plenty of applications, so it makes some kind of
sense. The fact that this needs not to be marked clearly by,
say, having string literals accessed only by const char*
is due to historical reasons.
If you get away with modifying a string literal, then you are
unlucky -- on the next computer or with the next version of
your compiler, this may be different.
So, if you want to "do" something with string literals, use
them to initialise arrays of char; if you need only the literal,
then you might be better of with const char*, i.e.

const char *not_to_be_modified = "42";
char buf[] = "State: Initial ";


Cheers
Michael
 
R

Roger Leigh

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

One thing which is not clear is that why a string literal is stored
in non modifiable memory. What if I don't use any ROM for the
execution of my program. Then can't I modify it ?

This is implementation-defined.

On GNU/Linux, for example, string literals will be stored in the
..rodata (read-only data) section of the ELF binary, and the run-time
linker ld.so will mmap() this section read-only (PROT_READ), unlike
..text (code) which will be readable and executable, but not writable
(PROT_READ|PROT_EXEC), or .data (modifiable data) which will be
(PROT_READ|PROT_WRITE). An attempt to modify (or execute) the string
literal will cause a segmentation violation and a core dump, due to
the read-only memory protection.

Other systems will do this differently: you'll need to check what your
specific compiler, linker and operating system do. In general,
modifying a string literal is always going to be a Bad Idea; current
versions of GCC don't allow it at all.


Regards,
Roger

- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFCiN6gVcFcaSW/uEgRAlmWAKDR3bt1xftM5saC49+xhMBM7W1MjQCeJEbF
mTjY6wQp/eAQYaEIFZldln8=
=/Nq6
-----END PGP SIGNATURE-----
 
K

Keith Thompson

Roger Leigh said:
This is implementation-defined.

On GNU/Linux, for example, string literals will be stored in the
.rodata (read-only data) section of the ELF binary, and the run-time
linker ld.so will mmap() this section read-only (PROT_READ), unlike
.text (code) which will be readable and executable, but not writable
(PROT_READ|PROT_EXEC), or .data (modifiable data) which will be
(PROT_READ|PROT_WRITE). An attempt to modify (or execute) the string
literal will cause a segmentation violation and a core dump, due to
the read-only memory protection.

Unless you use the gcc option that causes it to put string literals in
read-write memory. (I believe this option has been removed in the
latest version.)
 
B

Barry Schwarz

what would be the output for the following piece of code ?


if ( "hello" == "hello" )
printf("True\n");
else
printf("False\n");

What is the reason for that ?

It is an implementation detail whether there are one or two strings
with the value "hello" in your program.

int main(void)
{
char *str= "hello world";

str = "goodbye"; /* There is nothing wrong with this statement. It
is perfectly legal to modify str as often as you want. */

str[0] = 'G'; /* This statement is flawed. str points to a string
literal. While the literal is not formally defined as const, it
should be treated as such. The standard states that any attempt to
modify a string literal results in undefined behavior. */
}
I have seen may C tutorials that say that "str" cannot be
modified. What is the reason for that ? I tried this piece of
code on my machine and I was successfully able to modify it.

The code you posted does not modify either str or the data it points
to. What code did you try?



<<Remove the del for email>>
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top