A question on string literals

J

junky_fellow

char *str1 = "Hello";
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

Is it legal to modify str1, arr1 and arr2 ?
 
S

Sriram Rajagopalan

1.char *str1 = "Hello";

Generally the string literals would be stored in the read only data
section of the resulting object code, post compilation. So, modifying
the contents of the memory location addressed by "str1" would result in
seg fault. This might be compiler dependent though.

Although, "str1" itself can be modified.

The following is valid:
char *str1 = "Hello";
str1 = 0; // Allowed

2.char arr1[] = { "Hello" };

Contents of the memory addressed by "arr1" can be modified. "arr1"
itself cannot be modified.

That is the following is invalid:
char arr1[] = { "Hello" };
arr1 = 0; // Not allowed.

3. char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

Same comments as above for "arr2" hold true here.

-Sriram.
 
S

Suman

char *str1 = "Hello";
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

Is it legal to modify str1, arr1 and arr2 ?

FAQ 6.2 should be a good place to start.

To quote the draft:

The declaration
char arr1[] = { "Hello" };
defines a 'plain' char array object (of unknown size) `arr1' whose
elements
are initialized with character string literal. Array contents
are modifiable. This declaration is identical to
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };
as well as
char arr3[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

OTOH,
char *str1 = "Hello";
defines str1 with type 'pointer to char' and initializes it
to point to an object with type 'array of char' with length
6 whose elements are initialized with a character string literal.
If an attempt is made to use p to modify the contents of the array,
the behavior is undefined.
 
D

Default User

char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

This case has no string literal, in fact no string at all. It's an
array of five characters without a null terminator.




Brian
 
M

Mark

Default User said:
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

This case has no string literal, in fact no string at all. It's an
array of five characters without a null terminator.

No, it's an array of six characters and it DOES have a null terminator.
 
K

Kevin J. Phillips

Mark said:
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

This case has no string literal, in fact no string at all. It's an
array of five characters without a null terminator.

No, it's an array of six characters and it DOES have a null terminator.

% cat foo.c
#include <stdio.h>

int main(void)
{
char foo[] = { 'H', 'e', 'l', 'l', 'o' };

printf("%u\n", (unsigned)(sizeof foo));
return 0;
}
% gcc -Wall -ansi -pedantic foo.c
% ./a.out
5
 
M

Mark McIntyre

On 9 Aug 2005 02:09:27 -0700, in comp.lang.c ,
char *str1 = "Hello";

you can modify str1 (change where it points) but not what it currently
points to.
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

These are identical objects. You can modify what is inside them, but
not change arr1 or arr2.
 
E

Eric Sosman

Mark said:
On 9 Aug 2005 02:09:27 -0700, in comp.lang.c ,
char *str1 = "Hello";


you can modify str1 (change where it points) but not what it currently
points to.

char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };


These are identical objects. [...]

To quote Default User, elsethread: "Wanna bet?"
 
K

Keith Thompson

Mark McIntyre said:
On 9 Aug 2005 02:09:27 -0700, in comp.lang.c ,
char *str1 = "Hello";

you can modify str1 (change where it points) but not what it currently
points to.
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

These are identical objects. You can modify what is inside them, but
not change arr1 or arr2.

No, they're not identical. arr1 has a '\0' terminator; arr2 doesn't.

You can modify the values of arr1 and arr2, since they're (non-const)
array objects. (Their names decay to pointers in most contexts, and
of course you can't change the values of the pointers to which they
decay.)
 
J

John Bode

Mark said:
Default User said:
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

This case has no string literal, in fact no string at all. It's an
array of five characters without a null terminator.

No, it's an array of six characters and it DOES have a null terminator.

Only if the compiler is busticated. Let's try this again:

char arr2[] = {72, 101, 108, 108, 111};

How many elements are in the array? Is there a 0-valued element
anywhere in the array?
 
P

pete

char *str1 = "Hello";
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

Is it legal to modify str1, arr1 and arr2 ?

Depends on what you mean.

/* BEGIN new.c */

#include <stdio.h>
#include <string.h>

int main(void)
{
char *str1 = "Hello";
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

strcpy(arr1, ++str1);
strcpy(arr2, arr1);
puts(str1);
puts(arr1);
puts(arr2);
return 0;
}

/* END new.c */
 
J

Joe Wright

Mark said:
(e-mail address removed) wrote:

char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

This case has no string literal, in fact no string at all. It's an
array of five characters without a null terminator.


No, it's an array of six characters and it DOES have a null terminator.
Nonsense.

#include <stdio.h>
int main(void) {
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };
printf("%d\n", (int)sizeof arr2);
return 0;
}

Prints..
5
 
P

pete

Default said:
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

strcpy(arr2, arr1);
puts(arr2);

Please read the other posts from earlier in the day about arr2 NOT
being a string. Don't do stringy things with such a monster.

I used the array correctly.
Whether or not arr2 initially contains a string,
has nothing to do with whether or not arr2 can be modified
as per OP's question, and it has nothing to do with
whether or not arr2 can be a destination for strcpy.
 
N

Netocrat

pete said:
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

strcpy(arr2, arr1);
puts(arr2);


Please read the other posts from earlier in the day about arr2 NOT
being a string. Don't do stringy things with such a monster.

In this case, if we replace some of the lines you snipped,
char *str1 = "Hello";
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

strcpy(arr1, ++str1);
strcpy(arr2, arr1);
puts(str1);
puts(arr1);
puts(arr2);

we see that since str1 was first incremented, arr2 contains sufficient
space to hold the copied string.
 
M

Mark McIntyre

Mark said:
On 9 Aug 2005 02:09:27 -0700, in comp.lang.c ,
char arr1[] = { "Hello" };
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };


These are identical objects. [...]

To quote Default User, elsethread: "Wanna bet?"

and I'd lose, of course. They're identical in that you can modify them
both in much the same way. I forgot that arr1 has an extra element.
 
C

Chris Barts

1.char *str1 = "Hello";

Generally the string literals would be stored in the read only data
section of the resulting object code, post compilation. So, modifying
the contents of the memory location addressed by "str1" would result in
seg fault. This might be compiler dependent though.

That specific behavior is compiler-dependent, but modifying string literals
is not allowed by the Standard (any of them). Since this newsgroup deals with
the standards and how they relate to various programs and programming constructs,
it's better to say that the behavior is undefined.
Although, "str1" itself can be modified.

The following is valid:
char *str1 = "Hello";
str1 = 0; // Allowed

To be more clear, you might replace 0 with NULL. This is just a stylistic issue.
2.char arr1[] = { "Hello" };

Contents of the memory addressed by "arr1" can be modified. "arr1"
itself cannot be modified.

That is the following is invalid:
char arr1[] = { "Hello" };
arr1 = 0; // Not allowed.

No, that is still allowed: The array 'decomposes' into a pointer and
you can modify a non-const-qualified pointer at will.

What's giving me fits is what that is a pointer /to/. I don't think the
line of code is valid, in other words. It would be just fine if it was
defined like this:

char *arr1[] = { "Hello" };

As it stands, however, I don't think the definition is valid.
3. char arr2[] = { 'H', 'e', 'l', 'l', 'o' };

Same comments as above for "arr2" hold true here.

Well, no. arr2 is an array of char of size 5, but it cannot be used
as a string by most standard string-handing functions as it lacks
nul-termination. An array can decompose into a pointer to the first
element under certain conditions (such as when it is passed into or
returned from a function) and that array would decompose into a
pointer to char. Since nothing is const-qualified, you can modify that
array's contents and the value of the pointer it can decompose into.

Thus, both of these are legal:

arr2[1] = 'a'; /* The array is now 'Hallo' */
arr2 = NULL; /* The array is now unreachable. */
 

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

Similar Threads

K&R2, exercise 5-4, strend(s,t) 15
Simple question python 2
[memcpy] dst=NULL,size=0 9
Const Issue 2
Parsing a string 44
const problem 1
An array is just a pointer 146
Blue J Ciphertext Program 2

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top