What is the point of initializing a string pointer in C - c

Here is my question. in C, i saw code like this:
char *s = "this is a string";
but then, s is not actually pointing to an actual memory right?
and if you try to use s to modify the string, the result is undefined.
my question is, what is the point of assigning a string to the pointer
then?
thanks.

char *s = "this is a string";
This is a string literal. So the string is stored in read-only location and that memory address is returned to s . So when you try to write to the read-only location you see undefined behavior and might see a crash.
Q1:s is not actually pointing to an actual memory right?
You are wrong s is holding the memory address where this string is stored.
Q2:what is the point of assigning a string to the pointer then?
http://en.wikipedia.org/wiki/String_literal

When you do a char *s = "this is a string";, the memory is automatically allocated and populated with this string and a pointer to that memory is returned back to the caller (you). So, you do not need to explicitly put the string to some memory.
s is not actually pointing to an actual memory right?
Wrong, it does point to an actual memory whose allocation implementation is hidden from you. And this memory lies in the Read-Only sector of memory, so that it can't be changed/modified. Hence the keyword const as these literals are called constant literals.
if you try to use s to modify the string, the result is undefined.
Because, you are trying to modify memory which is marked as Read-Only.
what is the point of assigning a string to the pointer then?
Another way to achieve the same is,
char temp[260] = {0} ;
char *s ;
strcpy (temp, "this is a string");
s = temp ;
Here the memory temp is managed by you.
char *s = "this is a string" ;
Here the memory is managed by the OS.

By using const char * instead of a char [] the string will be stored in read only memory space. This allows the compiler to eliminate string duplication.
Try running this program:
#include <stdio.h>
int main()
{
const char *s1 = "This is a string";
const char *s2 = "This is a string";
if (s1 == s2) {
puts("s1 == s2");
} else {
puts("s1 != s2");
}
}
For the me it outputs s1 == s2 which means that the string pointers point to the same memory location.
Now try replacing const char * with char []:
int main()
{
const char s1[] = "This is a string";
const char s2[] = "This is a string";
if (s1 == s2) {
puts("s1 == s2");
} else {
puts("s1 != s2");
}
}
This outputs s1 != s2 which means that the compiler had to duplicate the string memory.
By using char * instead of char [] the compiler can do these optimizations that will decrease the size of you executable file.
Also note that you should not use char *s = "string". You should use const char *s = "string" instead. char *s is deprecated and unsafe. By using const char * you avoid the mistake of passing the string to a function that tries to modify the string.

s is not actually pointing to an actual memory right?
Technically, it is pointing to read-only memory. But the compiler is allowed to do whatever it wants as long as if follows the as-if rule. For example, if you never use s, it can be removed from your code completely.
Since it is read-only, any attempt to modify it is undefined behaviour. You can and should use const to indicate that the target of a pointer is immutable:
const char* s = "Hello const";
my question is, what is the point of assigning a string to the pointer then?
Just like storing a constant to any other type. You don't always need to modify strings. But you may want to pass a pointer to a string around to functions that don't care whether they point to a literal or to an array you own:
void foo(const char* str) {
// I won't modify the target of str. I don't care who owns it.
printf("foo: %s", str);
}
void bar(const char* str) {}
char* a = "Hello, this is a literal";
char b[] = "Hello, this is a char array and I own it";
foo(a);
bar(a);
foo(b);

Look at this code:
char *s = "this is a string";
printf("%s",s);
as you can see,I used "assigning a string to the pointer".Is that clear?
And know that s is pointing to an actual memory,but it is read-only.

If you are assigning like this,
char *s = "this is a string";
It will stored in the read only memory. So this is the reason for the undefined behavior. In this s will pointing to the some memory in the read-only area.
If you print the address like this you can get the some memory address.
printf("%p",s);
So in this case, if you allocate a memory and the copy the value to that pointer, you can access that pointer like array.

Everybody else has told you about the read-only memory and potential for undefined behavior if you attempt to modify the string, so I'll skip that part and answer the question, "what is the point of assigning a string to a pointer then?".
There are two reasons why
1) Just for brevity. After assigning the string to the pointer you can refer to the string as s instead of repeatedly typing "this is a string". This assumes of course that you intend to use the string in multiple function calls.
2) Because you may want to change the string that the pointer references. For example, in the following code, s is initialized assuming that the code will succeed, and is subsequently changed if there's a failure. At the end, the string that s points to is printed.
const char *s = "Yay, it worked!!!";
if ( openTheFile() == FAILED )
s = "Dang, couldn't open the file";
else if ( readTheFile() == FAILED )
s = "Oops, there's nothing in the file";
printf( "%s\n", s );
Note that const char * means that the string that s points to cannot be changed. It doesn't mean that s itself can't be changed.

In your case the pointer s is just pointing to the location that carries the first literal of the string. So if we want to change the string, it creates confusion as pointer s is pointing to the previous location. And if you want to change string using pointer, you should take care of the previous string's ending (i.e NULL).

Related

Reveres the string doesn't work in C [duplicate]

I have been struggling for a few hours with all sorts of C tutorials and books related to pointers but what I really want to know is if it's possible to change a char pointer once it's been created.
This is what I have tried:
char *a = "This is a string";
char *b = "new string";
a[2] = b[1]; // Causes a segment fault
*b[2] = b[1]; // This almost seems like it would work but the compiler throws an error.
So is there any way to change the values inside the strings rather than the pointer addresses?
When you write a "string" in your source code, it gets written directly into the executable because that value needs to be known at compile time (there are tools available to pull software apart and find all the plain text strings in them). When you write char *a = "This is a string", the location of "This is a string" is in the executable, and the location a points to, is in the executable. The data in the executable image is read-only.
What you need to do (as the other answers have pointed out) is create that memory in a location that is not read only--on the heap, or in the stack frame. If you declare a local array, then space is made on the stack for each element of that array, and the string literal (which is stored in the executable) is copied to that space in the stack.
char a[] = "This is a string";
you can also copy that data manually by allocating some memory on the heap, and then using strcpy() to copy a string literal into that space.
char *a = malloc(256);
strcpy(a, "This is a string");
Whenever you allocate space using malloc() remember to call free() when you are finished with it (read: memory leak).
Basically, you have to keep track of where your data is. Whenever you write a string in your source, that string is read only (otherwise you would be potentially changing the behavior of the executable--imagine if you wrote char *a = "hello"; and then changed a[0] to 'c'. Then somewhere else wrote printf("hello");. If you were allowed to change the first character of "hello", and your compiler only stored it once (it should), then printf("hello"); would output cello!)
No, you cannot modify it, as the string can be stored in read-only memory. If you want to modify it, you can use an array instead e.g.
char a[] = "This is a string";
Or alternately, you could allocate memory using malloc e.g.
char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done
A lot of folks get confused about the difference between char* and char[] in conjunction with string literals in C. When you write:
char *foo = "hello world";
...you are actually pointing foo to a constant block of memory (in fact, what the compiler does with "hello world" in this instance is implementation-dependent.)
Using char[] instead tells the compiler that you want to create an array and fill it with the contents, "hello world". foo is the a pointer to the first index of the char array. They both are char pointers, but only char[] will point to a locally allocated and mutable block of memory.
The memory for a & b is not allocated by you. The compiler is free to choose a read-only memory location to store the characters. So if you try to change it may result in seg fault. So I suggest you to create a character array yourself. Something like: char a[10]; strcpy(a, "Hello");
It seems like your question has been answered but now you might wonder why char *a = "String" is stored in read-only memory. Well, it is actually left undefined by the c99 standard but most compilers choose to it this way for instances like:
printf("Hello, World\n");
c99 standard(pdf) [page 130, section 6.7.8]:
The declaration:
char s[] = "abc", t[3] = "abc";
defines "plain" char array objects s and t whose elements are initialized with character string literals.
This declaration is identical to char
s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
The contents of the arrays are modifiable. On the other hand, the declaration
char *p = "abc";
defines p with type "pointer to char" and initializes it to point to an object with type "array of char" with length 4 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.
You could also use strdup:
The strdup() function returns a pointer to a new string which is a duplicate of the string s.
Memory for the new string is obtained with malloc(3), and can be freed with free(3).
For you example:
char *a = strdup("stack overflow");
All are good answers explaining why you cannot modify string literals because they are placed in read-only memory. However, when push comes to shove, there is a way to do this. Check out this example:
#include <sys/mman.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int take_me_back_to_DOS_times(const void *ptr, size_t len);
int main()
{
const *data = "Bender is always sober.";
printf("Before: %s\n", data);
if (take_me_back_to_DOS_times(data, sizeof(data)) != 0)
perror("Time machine appears to be broken!");
memcpy((char *)data + 17, "drunk!", 6);
printf("After: %s\n", data);
return 0;
}
int take_me_back_to_DOS_times(const void *ptr, size_t len)
{
int pagesize;
unsigned long long pg_off;
void *page;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize < 0)
return -1;
pg_off = (unsigned long long)ptr % (unsigned long long)pagesize;
page = ((char *)ptr - pg_off);
if (mprotect(page, len + pg_off, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
return -1;
return 0;
}
I have written this as part of my somewhat deeper thoughts on const-correctness, which you might find interesting (I hope :)).
Hope it helps. Good Luck!
You need to copy the string into another, not read-only memory buffer and modify it there. Use strncpy() for copying the string, strlen() for detecting string length, malloc() and free() for dynamically allocating a buffer for the new string.
For example (C++ like pseudocode):
int stringLength = strlen( sourceString );
char* newBuffer = malloc( stringLength + 1 );
// you should check if newBuffer is 0 here to test for memory allocaton failure - omitted
strncpy( newBuffer, sourceString, stringLength );
newBuffer[stringLength] = 0;
// you can now modify the contents of newBuffer freely
free( newBuffer );
newBuffer = 0;
char *a = "stack overflow";
char *b = "new string, it's real";
int d = strlen(a);
b = malloc(d * sizeof(char));
b = strcpy(b,a);
printf("%s %s\n", a, b);

Understanding char *, char[] and strcpy()

My understanding is as follows:
char * points to a string constant, modifying the data it points to is undefined. You can, however, change where it points to.
char[] refers to a block of memory that you can change. You can change its contents but not what it refers to.
strcpy(dest, src) copies src into dest.
My question is, is it incorrect to use strcpy() with the dest being a char * that is already pointing to something (as I believe the old contents will be overwritten by strcpy() - which is undefined behaviour)?
For example:
char *dest = malloc(5);
dest = "FIVE";
char *src = malloc(5);
src = "NEW!";
strcpy(dest, src); /* Invalid because chars at dest are getting overwritten? */
Your understanding is not totally correct, unfortunately.
char * points at character data, and since there's no const in there, you can write to the data being pointed to.
However, it's perfectly possible to do this:
char *a = "hello";
which gives you a read/write pointer to read-only data, since string literals are stored in read-only memory, but not "considered" constant by the language's syntax.
It's better to write the above as:
const char *a = "hello";
To make it more clear that you cannot modify the data pointed at by a.
Also, your examples mixing malloc() and assignment are wrong.
This:
char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */
Is bad code, and you should never do that. It simply overwrites the pointer returned by dest with a pointer to the string "FIVE" which exists somewhere in (again, read-only) memory as a string literal.
The proper way to initalize newly allocated memory with string data is to use strcpy():
char *dest = malloc(5);
if(dest != NULL)
strcpy(dest, "five");
Note that checking the return value of malloc() is a good idea.
There's no problem doing multiple writes to the same memory, that's a very basic idea in C; variables represent memory, and can be given different values at different times by being "written over".
Something as simple as:
int a = 2;
printf("a=%d\n", a);
a = 4;
printf("a=%d\n", a);
demonstrates this, and it works just fine for strings too of course since they are just blocks of memory.
You can extend the above malloc()-based example:
char *dest = malloc(5);
if(dest != NULL)
{
strcpy(dest, "five");
printf("dest='%s'\n", dest);
strcpy(dest, "four");
printf("dest='%s'\n", dest);
strcpy(dest, "one");
printf("dest='%s'\n", dest);
}
and it will print:
dest='five'
dest='four'
dest='one'
My understanding is as follows:
char * points to a string constant, modifying the data it points to is undefined. You can however change where it points to.
Here you refer to an expression like
char * string = "mystring";
You are right that doing string[1]='r'; is undefined. But that is not because of the char *, but because of the string literal involved in a way that it is put into read-only memory.
Compare this to
char string[] = "mystring";
where I define an array in RAM where the said string is put into. Here it is allowed to do string[1] = 'r';, because we are in normal data memory.
This seems to support your assumption, but take this:
char string[] = "mystring";
char * string2 = string;
Here string2[1] = 'r'; is valid, because it points to a location where writing is ok as well.
char[] refers to a block of memory that you can change its contents but not what it refers to.
Yes, because there the name is just the name of a variable and not a pointer.
strcpy(dest, src) copies src into dest.
Right.
My question is, is it incorrect to use strcpy() with the dest being a
char * that is already pointing to something (as I beleive the old
contents will be overwritten by strcpy() - which is undefined
behaviour)?
It depends what you mean with "already pointing to something"...
For example:
char *dest = malloc(5);
dest = "FIVE";
char *src = malloc(5);
src = "NEW!";
strcpy(dest, src); /* Invalid because chars at dest are getting
overwritten? */
Here you again mix up several things.
First, you have dest point to a brand new chunk of memory. Afterwards, you have it point to somewhere else where you cannot write, and the chunk of memory is lost (memory leak).
The same happens with src.
So the strcpy() fails.
You can do
char *dest = malloc(5);
char *src = "NEW!";
strcpy(dest, src);
as here dest points to a writable place, and src points to useful data.
A quick analysis:
char *dest = malloc(5);
// 'dest' is set to point to a piece of allocated memory
// (typically located in the heap)
dest = "FIVE";
// 'dest' is set to point to a constant string
// (typically located in the code-section or in the data-section)
You are assigning variable dest twice, so obviously, the first assignment has no meaning.
It's like writing:
int i = 5;
i = 6;
On top of that, you "lose" the address of the allocated memory, so you will not be able to release it later.
char* is a pointer to a memory adress, so you CAN modify the information contained at that adress.
The difference between char* and char[] is that char[] is not dynamic, you can't change its size. Also, char * points to a adress at the heap while char[] is stored at the stack of your program.
You can use strcpy with both pointers and arrays and it will work since data from both can be overwritten.

How does return of pointer work in strcat()

Hey guys I'm trying to figure how pointers are returned by strcat(), so I tried implementing my own strcat() to see how it works. The following is my code for mystrcat(), which works like the real strcat():
char *mystrcat(char *destination, char *source)
{
char *str = destination;
while (*str != '\0')
{
str++;
}
while (*source != '\0')
{
*str = *source;
str++;
source++;
}
*str = '\0';
return str;
}
So let's say in my main(), I have
char string[BUFSIZ];
mystrcat(string, "hello");
printf("%s\n", string);
The output would be
hello
as expected. What I don't get is how returning the address of the local variable, str, would magically make the variable, string, point to it and also why is the variable, str, not deleted when the function terminates.
You're not returning the address of the local variable. You're returning the value of the local variable. Since the variable in question is a pointer, its value happens to be an address. The address that is contained in the str variable points into the memory block provided by the argument destination.
What you seem to be misunderstanding is that this:
char* str = destination;
Does not create a copy of the destination string. It creates a pointer called str that points at the same memory location that destination points to. When you use str to manipulate the characters in that memory block, the string represented by destination is also modified, because str and destination point into the exact same string of characters in memory. That's how it "magically updates" the parameter.
str is a pointer to the string you pass in (destination), so you are modifying your original variable string from within your strcat function.
The pointer str does get deleted at the end of the routine, but it is not needed anymore.
BTW, it is confusing to use the word "string" as the name of a variable, because many languages reserve string as a keyword.
The first line of the function, you're assigning *str to be the same as *destination. In effect, when you return, you're returning *destination, which is the same as *str.
No memory is allocated, so no memory must be deleted.

Is it possible to modify a string of char in C?

I have been struggling for a few hours with all sorts of C tutorials and books related to pointers but what I really want to know is if it's possible to change a char pointer once it's been created.
This is what I have tried:
char *a = "This is a string";
char *b = "new string";
a[2] = b[1]; // Causes a segment fault
*b[2] = b[1]; // This almost seems like it would work but the compiler throws an error.
So is there any way to change the values inside the strings rather than the pointer addresses?
When you write a "string" in your source code, it gets written directly into the executable because that value needs to be known at compile time (there are tools available to pull software apart and find all the plain text strings in them). When you write char *a = "This is a string", the location of "This is a string" is in the executable, and the location a points to, is in the executable. The data in the executable image is read-only.
What you need to do (as the other answers have pointed out) is create that memory in a location that is not read only--on the heap, or in the stack frame. If you declare a local array, then space is made on the stack for each element of that array, and the string literal (which is stored in the executable) is copied to that space in the stack.
char a[] = "This is a string";
you can also copy that data manually by allocating some memory on the heap, and then using strcpy() to copy a string literal into that space.
char *a = malloc(256);
strcpy(a, "This is a string");
Whenever you allocate space using malloc() remember to call free() when you are finished with it (read: memory leak).
Basically, you have to keep track of where your data is. Whenever you write a string in your source, that string is read only (otherwise you would be potentially changing the behavior of the executable--imagine if you wrote char *a = "hello"; and then changed a[0] to 'c'. Then somewhere else wrote printf("hello");. If you were allowed to change the first character of "hello", and your compiler only stored it once (it should), then printf("hello"); would output cello!)
No, you cannot modify it, as the string can be stored in read-only memory. If you want to modify it, you can use an array instead e.g.
char a[] = "This is a string";
Or alternately, you could allocate memory using malloc e.g.
char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done
A lot of folks get confused about the difference between char* and char[] in conjunction with string literals in C. When you write:
char *foo = "hello world";
...you are actually pointing foo to a constant block of memory (in fact, what the compiler does with "hello world" in this instance is implementation-dependent.)
Using char[] instead tells the compiler that you want to create an array and fill it with the contents, "hello world". foo is the a pointer to the first index of the char array. They both are char pointers, but only char[] will point to a locally allocated and mutable block of memory.
The memory for a & b is not allocated by you. The compiler is free to choose a read-only memory location to store the characters. So if you try to change it may result in seg fault. So I suggest you to create a character array yourself. Something like: char a[10]; strcpy(a, "Hello");
It seems like your question has been answered but now you might wonder why char *a = "String" is stored in read-only memory. Well, it is actually left undefined by the c99 standard but most compilers choose to it this way for instances like:
printf("Hello, World\n");
c99 standard(pdf) [page 130, section 6.7.8]:
The declaration:
char s[] = "abc", t[3] = "abc";
defines "plain" char array objects s and t whose elements are initialized with character string literals.
This declaration is identical to char
s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
The contents of the arrays are modifiable. On the other hand, the declaration
char *p = "abc";
defines p with type "pointer to char" and initializes it to point to an object with type "array of char" with length 4 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.
You could also use strdup:
The strdup() function returns a pointer to a new string which is a duplicate of the string s.
Memory for the new string is obtained with malloc(3), and can be freed with free(3).
For you example:
char *a = strdup("stack overflow");
All are good answers explaining why you cannot modify string literals because they are placed in read-only memory. However, when push comes to shove, there is a way to do this. Check out this example:
#include <sys/mman.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int take_me_back_to_DOS_times(const void *ptr, size_t len);
int main()
{
const *data = "Bender is always sober.";
printf("Before: %s\n", data);
if (take_me_back_to_DOS_times(data, sizeof(data)) != 0)
perror("Time machine appears to be broken!");
memcpy((char *)data + 17, "drunk!", 6);
printf("After: %s\n", data);
return 0;
}
int take_me_back_to_DOS_times(const void *ptr, size_t len)
{
int pagesize;
unsigned long long pg_off;
void *page;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize < 0)
return -1;
pg_off = (unsigned long long)ptr % (unsigned long long)pagesize;
page = ((char *)ptr - pg_off);
if (mprotect(page, len + pg_off, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
return -1;
return 0;
}
I have written this as part of my somewhat deeper thoughts on const-correctness, which you might find interesting (I hope :)).
Hope it helps. Good Luck!
You need to copy the string into another, not read-only memory buffer and modify it there. Use strncpy() for copying the string, strlen() for detecting string length, malloc() and free() for dynamically allocating a buffer for the new string.
For example (C++ like pseudocode):
int stringLength = strlen( sourceString );
char* newBuffer = malloc( stringLength + 1 );
// you should check if newBuffer is 0 here to test for memory allocaton failure - omitted
strncpy( newBuffer, sourceString, stringLength );
newBuffer[stringLength] = 0;
// you can now modify the contents of newBuffer freely
free( newBuffer );
newBuffer = 0;
char *a = "stack overflow";
char *b = "new string, it's real";
int d = strlen(a);
b = malloc(d * sizeof(char));
b = strcpy(b,a);
printf("%s %s\n", a, b);

Why does *(str+i) = *(str +j) not work here?

void reverse(char *str){
int i,j;
char temp;
for(i=0,j=strlen(str)-1; i<j; i++, j--){
temp = *(str + i);
*(str + i) = *(str + j);
*(str + j) = temp;
printf("%c",*(str + j));
}
}
int main (int argc, char const *argv[])
{
char *str = "Shiv";
reverse(str);
printf("%s",str);
return 0;
}
When I use char *str = "Shiv" the lines in the swapping part of my reverse function i.e str[i]=str[j] dont seem to work, however if I declare str as char str[] = "Shiv", the swapping part works? What is the reason for this. I was a bit puzzled by the behavior, I kept getting the message "Bus error" when I tried to run the program.
When you use char *str = "Shiv";, you don't own the memory pointed to, and you're not allowed to write to it. The actual bytes for the string could be a constant inside the program's code.
When you use char str[] = "Shiv";, the 4(+1) char bytes and the array itself are on your stack, and you're allowed to write to them as much as you please.
The char *str = "Shiv" gets a pointer to a string constant, which may be loaded into a protected area of memory (e.g. part of the executable code) that is read only.
char *str = "Shiv";
This should be :
const char *str = "Shiv";
And now you'll have an error ;)
Try
int main (int argc, char const *argv[])
{
char *str = malloc(5*sizeof(char)); //4 chars + '\0'
strcpy(str,"Shiv");
reverse(str);
printf("%s",str);
free(str); //Not needed for such a small example, but to illustrate
return 0;
}
instead. That will get you read/write memory when using pointers. Using [] notation allocates space in the stack directly, but using const pointers doesn't.
String literals are non-modifiable objects in both C and C++. An attempt to modify a string literal always results in undefined behavior. This is exactly what you observe when you get your "Bus error" with
char *str = "Shiv";
variant. In this case your 'reverse' function will make an attempt to modify a string literal. Thus, the behavior is undefined.
The
char str[] = "Shiv";
variant will create a copy of the string literal in a modifiable array 'str', and then 'reverse' will operate on that copy. This will work fine.
P.S. Don't create non-const-qualified pointers to string literals. You first variant should have been
const char *str = "Shiv";
(note the extra 'const').
String literals (your "Shiv") are not modifiable.
You assign to a pointer the address of such a string literal, then you try to change the contents of the string literal by dereferencing the pointer value. That's a big NO-NO.
Declare str as an array instead:
char str[] = "Shiv";
This creates str as an array of 5 characters and copies the characters 'S', 'h', 'i', 'v' and '\0' to str[0], str[1], ..., str[4]. The values in each element of str are modifiable.
When I want to use a pointer to a string literal, I usually declare it const. That way, the compiler can help me by issuing a message when my code wants to change the contents of a string literal
const char *str = "Shiv";
Imagine you could do the same with integers.
/* Just having fun, this is not C! */
int *ptr = &5; /* address of 5 */
*ptr = 42; /* change 5 to 42 */
printf("5 + 1 is %d\n", *(&5) + 1); /* 6? or 43? :) */
Quote from the Standard:
6.4.5 String literals
...
6 ... If the program attempts to modify such an array [a string literal], the behavior is undefined.
char *str is a pointer / reference to a block of characters (the string). But its sitting somewhere in a block of memory so you cannot just assign it like that.
Interesting that I've never noticed this. I was able to replicate this condition in VS2008 C++.
Typically, it is a bad idea to do in-place modification of constants.
In any case, this post explains this situation pretty clearly.
The first (char[]) is local data you can edit
(since the array is local data).
The second (char *) is a local pointer to
global, static (constant) data. You
are not allowed to modify constant
data.
If you have GNU C, you can compile
with -fwritable-strings to keep the
global string from being made
constant, but this is not recommended.

Resources