Vous êtes sur la page 1sur 5

string - What is the difference between char s[] and char *s in C? - Stack...

1 trong 5

http://stackoverflow.com/questions/1704407/what-is-the-difference-betwee...

Stack Overflow is a question and answ er site for professional and enthusiast programmers. It's 100% free, no
registration required.

Tell me more

What is the difference between char s[] and char *s in C?

In C, I can do like this:


char s[]="hello";
or
char *s ="hello";
So I wonder what is the difference? I want to know what actually happens in memory allocation during
compile time and run time.
c

string

char

constants

edited May 15 '12 at 21:12


Flexo
34.1k 9 56 105

asked Nov 9 '09 at 22:34


tsubasa
2,796 8 41 75

5 c-faq.com/aryptr/index.html c-faq.com/charstring/index.html Sinan nr Nov 9 '09 at 23:22


2 char *s="hello", here s can point any another string at run time I mean it is not constant pointer you
can assign another value at run time p = "Nishant", while s[] here s is constant pointer....it can't be
reasign another string but we can assign another character value at s[index]. Nishant May 16 '12
at 14:49

9 Answers
The difference here is that
char *s = "Hello world";
will place Hello world in the read-only parts of the memory and making s a pointer to that, making any
writing operation on this memory illegal. While doing:
char s[] = "Hello world";
puts the literal string in read-only memory and copies the string to newly allocated memory on the stack.
Making
s[0] = 'J';
legal.
edited Nov 9 '09 at 22:46

answered Nov 9 '09 at 22:38


Rickard
1,856 1 9 8

4 The literal string "Hello world" is in "read-only parts of the memory" in both examples. The
example with the array points there, the example with the array copies the characters to the array
elements. pmg Nov 9 '09 at 22:42

11/16/2013 7:30 AM

string - What is the difference between char s[] and char *s in C? - Stack...

2 trong 5

http://stackoverflow.com/questions/1704407/what-is-the-difference-betwee...

5 pmg: In the second case the literal string does not necessarily exist in memory as a single contiguous
object at all - it's just an initialiser, the compiler could quite resonably emit a series of "load
immediate byte" instructions that contain the character values embedded within them. caf Nov 9
'09 at 22:46

3 The char array example does not necessarily place the string on the stack - if it appears at file level,
it will probably be in some kind of initialised data segment instead. caf Nov 9 '09 at 22:47

1 @caf, @Charles: The Standard (n1401.pdf) says @ 6.4.5 String literals /5 "... The multibyte
character sequence is then used to initialize an array of static storage duration and length
just sufficient to contain the sequence. ..." It doesn't "speak" of 'plain' character sequences,
but I think the same applies. I also think an implementation can ignore this particular bit of the
Standard for performance reasons :) pmg Nov 9 '09 at 23:00

2 I'd like to point out that char s = "xx" doesn't have to be in read-only memory (some implementations
have no MMUs, for example). The n1362 c1x draft simply states that modifying such an array causes
undefined behavior. But +1 anyway, since relying on that behavior is a silly thing to do. paxdiablo
Nov 10 '09 at 12:35
show 3 more comments

First off, in function arguments, they are exactly equivalent:


void foo(char *x);
void foo(char x[]); // exactly the same in all respects (note! this only applies if the brackets are empt
In other contexts, char * allocates a pointer, while char [] allocates an array. Where does the string go
in the former case, you ask? The compiler secretly allocates a static anonymous array to hold the string
literal. So:
char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;
Note that you must not ever attempt to modify the contents of this anonymous array via this pointer; the
effects are undefined (often meaning a crash):
x[1] = 'O'; // BAD. DON'T DO THIS.
Using the array syntax directly allocates it into new memory. Thus modification is safe:
char x[] = "Foo";
x[1] = 'O'; // No problem.
However the array only lives as long as its contaning scope, so if you do this in a function, don't return or
leak a pointer to this array - make a copy instead with strdup() or similar. If the array is allocated in
global scope, of course, no problem.
edited Nov 10 '09 at 17:05

answered Nov 9 '09 at 22:45


bdonlan
78.9k 10 106 180

2 I think you meant x[1] = 'O'; (single quotes, not doubles). paxdiablo Nov 10 '09 at 12:37
Indeed I did, fixed. bdonlan Nov 10 '09 at 17:05

This declaration:
char s[] = "hello";
Creates one object - a char array of size 6, called s , initialised with the values 'h', 'e', 'l', 'l',
'o', '\0' . Where this array is allocated in memory, and how long it lives for, depends on where the
declaration appears. If the declaration is within a function, it will live until the end of the block that it is
declared in, and almost certainly be allocated on the stack; if it's outside a function, it will probably be
stored within an "initialised data segment" that is loaded from the executable file into writeable memory

11/16/2013 7:30 AM

string - What is the difference between char s[] and char *s in C? - Stack...

3 trong 5

http://stackoverflow.com/questions/1704407/what-is-the-difference-betwee...

when the program is run.


On the other hand, this declaration:
char *s ="hello";
Creates two objects:
a read-only array of 6 chars containing the values 'h', 'e', 'l', 'l', 'o', '\0', which has no
name and has static storage duration (meaning that it lives for the entire life of the program); and
a variable of type pointer-to-char, called s, which is initialised with the location of the first character
in that unnamed, read-only array.
The unnamed read-only array is typically located in the "text" segment of the program, which means it is
loaded from disk into read-only memory, along with the code itself. The location of the s pointer
variable in memory depends on where the declaration appears (just like in the first example).
edited Nov 9 '09 at 22:50

answered Nov 9 '09 at 22:42


caf
103k 8 100 226

1 In both declaration for "hello" memory is allocated at comiple time ?.And another thing char *p =
"hello" here "hello" is stored in text segment as you stated in your answer...and what about char s[] =
"hello" will it also store first in text segment part and during run time it will copy in stack as Rickard
has stated in there answer. please clarify this point. Nishant May 16 '12 at 15:00

2 @Nishant: In the char s[] = "hello" case, the "hello" is just an initialiser telling the compiler
how the array should be initialised. It may or may not result in a corresponding string in the text
segment - for example, if s has static storage duration then it is likely that the only instance of
"hello" will be in the initialised data segment - the object s itself. Even if s has automatic
storage duration, it can be initialised by a sequence of literal stores rather than a copy (eg. movl
$1819043176, -6(%ebp); movw $111, -2(%ebp) ). caf May 17 '12 at 1:28
Thanks caf for your clarification. Nishant May 17 '12 at 4:55

Given the declarations


char *s0 = "hello world";
char s1[] = "hello world";
assume the following hypothetical memory map:

s0:
s1:

0x00008000:
0x00008004:
0x00008008:
...
0x00010000:
0x00010004:
0x00010008:
0x0001000C:

0x01
'h'
'o'
'r'

0x02
'e'
' '
'l'

0x03
'l'
'w'
'd'

0x04
'l'
'o'
0x00

0x00
'h'
'o'
'r'

0x00
'e'
' '
'l'

0x80
'l'
'w'
'd'

0x00
'l'
'o'
0x00

The string literal "hello world" is a 12-element array of char (const char in C++) with static extent,
meaning that the memory for it is allocated when the program starts up and remains allocated until the
memory terminates. Attempting to modify the contents of a string literal invokes undefined behavior.
The line
char *s0 = "hello world";
defines s0 as a pointer to char with auto extent (meaning the variable s0 only exists for the scope in
which it is declared) and copies the address of the string literal (0x00008000 in this example) to it. Note
that since s0 points to a string literal, it should not be used as an argument to any function that would try
to modify it (e.g., strtok() , strcat() , strcpy() , etc.).
The line
char s1[] = "hello world";
defines s1 as a 12-element array of char (length is taken from the string literal) with auto extent and
copies the contents of the literal to the array. As you can see from the memory map, we have two copies
of the string "hello world"; the difference is that you can modify the string contained in s1 .

11/16/2013 7:30 AM

string - What is the difference between char s[] and char *s in C? - Stack...

4 trong 5

http://stackoverflow.com/questions/1704407/what-is-the-difference-betwee...

s0 and s1 are interchangeable in most contexts; here are the exceptions:


sizeof s0 == sizeof (char*)
sizeof s1 == 12
type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char
You can reassign the variable s0 to point to a different string literal or to another variable. You cannot
reassign the variable s1 to point to a different array.
answered Nov 9 '09 at 23:03
John Bode
27.4k 2 27 47

.
char s[] = "hello";
declares s to be a array of char which is long enough to hold the initializer (5 + 1 char s) and
initializes the array by copying the members of the given string literal into the array.
char *s = "hello";
declares s to be a pointer to one or more (in this case more) char s and points it directly at a fixed
(read-only) location containing the literal "hello" .
edited Nov 9 '09 at 22:49

answered Nov 9 '09 at 22:40


Charles Bailey
203k 33 289 425

1 What method is preferable to use in functions if s will not be changed, f(const char s[]) or f(const char
*s) ? psihodelia Nov 8 '11 at 13:26

1 @psihodelia: In a function declaration there is no difference. In both cases s is a pointer to const


char . Charles Bailey Nov 8 '11 at 14:20

In the light of comments here it should be obvious that : char * s = "hello" ; Is a bad idea, and should be
used in very narrow scope.
This might be a good opportunity to point out that "const correctness" is a "good thing". Whenever and
wherever You can, use the "const" keyword to protect your code, from "relaxed" callers or programmers,
which are usually most "relaxed" when pointers come into play.
Enough melodrama, here is what one can achieve when adorning pointers with "const". (Note: One has to
read pointer declarations right-to-left.) Here are the 3 different ways to protect yourself when playing with
pointers :
const DBJ* p means "p points to a DBJ that is const"
that is, the DBJ object can't be changed via p.
DBJ* const p means "p is a const pointer to a DBJ"
that is, you can change the DBJ object via p, but you can't change the pointer p itself.
const DBJ* const p means "p is a const pointer to a const DBJ"
that is, you can't change the pointer p itself, nor can you change the DBJ object via p.
The errors related to attempted const-ant mutations are caught at compile time. There is no runtime
space or speed penalty for const.
(Assumption is you are using C++ compiler, of course ?)
--DBJ
edited Nov 9 '09 at 23:27

answered Nov 9 '09 at 23:20


DBJDBJ
423 4 11

11/16/2013 7:30 AM

string - What is the difference between char s[] and char *s in C? - Stack...

5 trong 5

http://stackoverflow.com/questions/1704407/what-is-the-difference-betwee...

char s[] = "Hello world";


Here, s is an array of characters, which can be overwritten if we wish.
char *s = "hello";
A string literal is used to create these character blocks somewhere in the memory which this pointer s is
pointing to. We can here reassign the object it is pointing to by changing that, but as long as it points to a
string literal the block of characters to which it points can't be changed.
edited Apr 27 '12 at 15:10
Bo Persson
40.2k 9 41 87

answered Nov 9 '09 at 22:55


Sailaja
66 5

In the case of:


char *x = "fred";
x is an lvalue -- it can be assigned to. But in the case of:
char x[] = "fred";
x is not an lvalue, it is an rvalue -- you cannot assign to it.
answered Nov 9 '09 at 22:57
Lee-Man
310 1 7

2 Technically, x is a non-modifiable lvalue. In almost all contexts though, it will evaluate to a pointer
to its first element, and that value is an rvalue. caf Nov 9 '09 at 23:02

Just to add: you also get different values for their sizes.
printf("sizeof s[] = %d\n",sizeof(s));
printf("sizeof *s = %d\n",sizeof(s));
As mentioned above, for an array '\0' will be allocated as the final element.
edited Oct 20 at 18:44
hopper
2,771 2 11 24

answered Nov 21 '12 at


10:39
Muzab
11 1

protected by Bo Persson Apr 20 '12 at 18:12


This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you
must have earned at least 10 reputation on this site.

Not the answer you're looking for? Browse other questions tagged c string char
constants or ask your own question.

11/16/2013 7:30 AM