13
int main()
{
        char *x = "HelloWorld";
        char y[] = "HelloWorld";

        x[0] = 'Z';
        //y[0] = 'M';

        return 0;
}

In the above program, HelloWorld will be in read-only section(i.e string table). x will be pointing to that read-only section, so trying to modify that values will be undefined behavior.

But y will be allocated in stack and HelloWorld will be copied to that memory. so modifying y will works fine. String literals: pointer vs. char array

Here is my Question:

In the following program, both char *arr and char arr[] causes segmentation fault if the content is modified.

void function(char arr[])
//void function(char *arr)
{
   arr[0] = 'X';
}        
int main()
{
   function("MyString");    
   return 0;
}
  1. How it differs in the function parameter context?
  2. No memory will be allocated for function parameters??

Please share your knowledge.

Community
  • 1
  • 1
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • possible duplicate of [Sizeof array passed as parameter](http://stackoverflow.com/questions/1328223/sizeof-array-passed-as-parameter) –  Jun 14 '13 at 14:48
  • 2
    Not really related to a discussion of the size of an array parameter. This is about the const-ness of string literals vs character arrays, which is mostly unrelated to the sizes. – Jonathan Leffler Jun 14 '13 at 15:50

3 Answers3

27

Inside the function parameter list, char arr[] is absolutely equivalent to char *arr, so the pair of definitions and the pair of declarations are equivalent.

void function(char arr[]) { ... }
void function(char *arr)  { ... }

void function(char arr[]);
void function(char *arr);

The issue is the calling context. You provided a string literal to the function; string literals may not be modified; your function attempted to modify the string literal it was given; your program invoked undefined behaviour and crashed. All completely kosher.

Treat string literals as if they were static const char literal[] = "string literal"; and do not attempt to modify them.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    You can even say `static const char` to have the correct storage duration. – ouah Jun 14 '13 at 14:51
  • 1
    The C++ standard, in fact, does specify that string literals are `const`. Unfortunately, the C standard does not, presumably because this would break just too much legacy code that, while not modifying these literals, is sloppy in its declarations. – microtherion Jun 14 '13 at 14:54
  • @microtherion: yes, you're right about the legacy. GCC v3.x and earlier had an option `-fwriteable-strings` (with two e's IIRC, but maybe it was one), that made string literals writable instead of constant. GCC v4.x does not support that option; string literals are always non-writable. – Jonathan Leffler Jun 14 '13 at 14:58
  • I think the first sentence can be misunderstood, in a _function prototype_ the two are identical, not in a function body. I know that's what you meant, but maybe not every reader does. – Daniel Fischer Jun 14 '13 at 15:18
  • @DanielFischer: I see what you mean; does the revision resolve that? – Jonathan Leffler Jun 14 '13 at 15:48
  • Sure. One can't misunderstand that without bad intentions ;) – Daniel Fischer Jun 14 '13 at 15:53
8
function("MyString");

is similar to

char *s = "MyString";
function(s);

"MyString" is in both cases a string literal and in both cases the string is unmodifiable.

function("MyString");

passes the address of a string literal to function as an argument.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • In first case also, `HelloWorld` is string literal only in `char arr[]` case. right?? – Jeyaram Jun 14 '13 at 14:53
  • 1
    In the first code fragment, the string literal for `y` is an initializer that is copied to the stack. If the function were invoked multiple times, the array would be initialized on each invocation, presumably using a constant initializer from somewhere else. The array is modifiable, though. – Jonathan Leffler Jun 14 '13 at 14:55
2

char *arr; above statement implies that arr is a character pointer and it can point to either one character or strings of character

& char arr[]; above statement implies that arr is strings of character and can store as many characters as possible or even one but will always count on '\0' character hence making it a string ( e.g. char arr[]= "a" is similar to char arr[]={'a','\0'} )

But when used as parameters in called function, the string passed is stored character by character in formal arguments making no difference.