473,324 Members | 2,548 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,324 software developers and data experts.

c pointer and array question

hi:

please take a look at the following code fragment:

char* hello = "Hello World\n";

hello[5] = 's';

why I cannot modify hello[5]?

thanks,

bo

Nov 14 '05 #1
7 7394
Bo Sun <b0*****@cs.tamu.edu> spoke thus:
char* hello = "Hello World\n";
hello[5] = 's'; why I cannot modify hello[5]?


Short answer: Because the Standard says so.

hello points to a string literal. The Standard states that attempting
to modify a string literal (as you are trying to do) results in
undefined behavior. Some implementations may let you get away with it
anyway; however, in many (most?) cases, string literals are stored in
read-only memory, and attempting to modify the contents of such memory
is a sure way to cause problems for yourself.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #2
On Fri, 26 Dec 2003 11:47:16 -0600, Bo Sun <b0*****@cs.tamu.edu>
wrote:
hi:

please take a look at the following code fragment:

char* hello = "Hello World\n";

hello[5] = 's';

why I cannot modify hello[5]?

thanks,

bo


Christopher told you why. What you probably want to do is:

char hello[] = "Hello World\n";

Try that, then think about the difference.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #3
Bo Sun wrote:
hi:

please take a look at the following code fragment:

char* hello = "Hello World\n";
Never do this. You can't modify a string literal, so make your intention
to NOT modify it clear by making the pointer const:

const char *hello = "Hello World\n";

I would strongly recommend enabling the option to have your compiler
warn you about this, if you compiler has such an option. In gcc, the
option is -Wwrite-strings.

hello[5] = 's';
After the change above, this will cause your compiler to issue a
diagnostic. This is good, since modifying a string literal (or
attempting to) gives undefined behavior, and will probably crash your
program or worse.

why I cannot modify hello[5]?


You cannot modify a string literal.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #4
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote in message news:<bs**********@chessie.cirr.com>...
Bo Sun <b0*****@cs.tamu.edu> spoke thus:
char* hello = "Hello World\n";
hello[5] = 's';

why I cannot modify hello[5]?


Short answer: Because the Standard says so.

hello points to a string literal. The Standard states that attempting
to modify a string literal (as you are trying to do) results in
undefined behavior. Some implementations may let you get away with it
anyway; however, in many (most?) cases, string literals are stored in
read-only memory, and attempting to modify the contents of such memory
is a sure way to cause problems for yourself.


If you are intentionally using string literals--and I recognize you
are not in this case--you should use the const keyword. Then if you
did try to change it, the compiler would complain in most cases.
Note, however, that const can always be circumvented.

---
Jared Dykstra
http://www.bork.org/~jared
Nov 14 '05 #5
In article <news:Pi******************************@unix.cs.tam u.edu>
Bo Sun <b0*****@cs.tamu.edu> writes:
char* hello = "Hello World\n";
hello[5] = 's';

[does not work; why not?]

Others have already posted correct answers (which boil down to
"because the C standard says it does not have to work", and in your
case your C compiler makes sure it does not work), but I want to
clarify one bit. The thing with the double quotes above *is* a
"string literal", in the Standard's terminology, but the array to
which "hello" points is not actually a "string literal".

String literals are purely source-code constructs, rather like
keywords. If you write "int x, y;" then x and y have type "int",
but there is no requirement -- and often no actual -- run-time
information lying around saying "this memory over here is what was
originally named x, and has type int". One can reverse-engineer
object code and often figure out that "there is an int or long in
this memory over here", but perhaps not which one it is (int or
long), and in most cases, there is no way at all to recover the
name of the variable.

In any case, the anonymous array that the string literal produces
in this context has type "array 12 of char", rather than the more
logical "array 12 of const char". If you apply The Rule about
arrays and pointers in C (see http://web.torek.net/torek/c/pa.html),
you will find that "array 12 of char" is usable wherever a value
of type "char *" is required. Thus, this is a valid initializer
for the variable "hello" -- but the array's elements are allowed
to be, and your compiler makes them, read-only.

Note that when a string literal is used as an initializer for an
object of type "array N of char", the string literal does not (or
at least need not) produce any array of its own, and the characters
inside the string literal are used instead to initialize the object.
The "const"-ness (i.e., readonly-ness) of the object is then
controlled by the object's type: if it is "array 12 of char" it is
read/write; if it is "array 12 of const char" it is read-only.
I wrote a long article about this just a week or so ago.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #6
Christopher Benson-Manica <at***@nospam.cyberspace.org> writes:
Bo Sun <b0*****@cs.tamu.edu> spoke thus:
char* hello = "Hello World\n";
hello[5] = 's';

why I cannot modify hello[5]?


Short answer: Because the Standard says so.

hello points to a string literal. The Standard states that attempting
to modify a string literal (as you are trying to do) results in
undefined behavior. Some implementations may let you get away with it
anyway; however, in many (most?) cases, string literals are stored in
read-only memory, and attempting to modify the contents of such memory
is a sure way to cause problems for yourself.


A small (and mostly irrelevant) clarification:

In most systems, string literals are not actually stored in ROM (i.e.,
in memory chips whose contents physically cannot be modified by
software). They're usually stored in the same kind of RAM
(random-access read/write memory) as all the other code and data in
your operating system and programs. (I'll ignore virtual memory.)

When I ran a program that tried to modify a string literal, I got a
segmentation fault -- not because the string literal was stored in
ROM, but because the linker and operating system arranged for the
memory to be read-only for my program. It was written by the OS when
it loaded my program, and again when my program terminated.

In an embedded system, however, string literals, along with your
program's code, may be stored in some kind of ROM. In that case,
you'd have to burn your program to a ROM chip (or EEPROM, or whatever)
before you could run it.

The standard doesn't distinguish between these two cases. Trying to
modify a string literal results in undefined behavior, whether it's
because the memory is marked read-only by the OS, or because it's
burned into ROM, or because it's engraved on non-erasable stone
tablets. It could even succeed in modifying it; that's just one of
the infinitely many possible consequences of undefined behavior.

(Note that the phrase "modifying a string literal" is a shorthand. A
string literal exists only in a program's source code. What you're
trying to modify is the anonymous static array that's initialized from
the string literal.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 14 '05 #7
Keith Thompson <ks***@mib.org> spoke thus:
A small (and mostly irrelevant) clarification:
(string literal clarification)


Irrelevant? Hardly! I appreciate knowing all the details - thanks.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: overbored | last post by:
I can do this: int asdf; int* zxcv = asdf; but not this: int asdf; int** zxcv = asdf;
9
by: sangeetha | last post by:
Hello, Is there any performance difference in using of the following two declaration? int (*ptr); //Array of 10 int pointers int *ptr; // pointer-to-array of 10. Regards, Sangeetha.
11
by: x-pander | last post by:
given the code: <file: c.c> typedef int quad_t; void w0(int *r, const quad_t *p) { *r = (*p); }
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
28
by: Wonder | last post by:
Hello, I'm confused by the pointer definition such as int *(p); It seems if the parenthesis close p, it defines only 3 integers. The star is just useless. It can be showed by my program: ...
14
by: sheroork | last post by:
Can anyone help me in getting to understand pointer to pointer with examples? Appritiate in advance. Sagar
12
by: gcary | last post by:
I am having trouble figuring out how to declare a pointer to an array of structures and initializing the pointer with a value. I've looked at older posts in this group, and tried a solution that...
10
by: Zhou Yan | last post by:
I want to define a pointer to a multiple-subscripted array. For instance, I have an array defined as below( I have reduced the size of the array as well as the dimension, but I think it OK to ask...
25
by: Ioannis Vranos | last post by:
Are the following codes guaranteed to work always? 1. #include <iostream> inline void some_func(int *p, const std::size_t SIZE) {
9
by: subramanian100in | last post by:
The following portion is from c-faq.com - comp.lang.c FAQ list · Question 6.13 int a1 = {0, 1, 2}; int a2 = {{3, 4, 5}, {6, 7, 8}}; int *ip; /* pointer to int */ int (*ap); /* pointer to...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.