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)); } }  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; } int main (int argc, char const *argv[]) { char *str = "Shiv"; reverse(str); printf("%s",str); return 0; } 

When I use char * str = "Shiv", the strings in the swap part of my inverse function, i.e. str [i] = str [j] doesn't seem to work, however, if I declare str as char str [] = "Shiv" does swap work? What is the reason for this. I was a little puzzled by the behavior, I continued to receive a "Bus Error" message when I tried to start the program.

+4
source share
8 answers

When you use char *str = "Shiv"; , you do not own the specified memory, and you are not allowed to write to it. Actual bytes for a string can be a constant inside the program code.

When you use char str[] = "Shiv"; , bytes 4 (+1) char and the array itself are on your stack, and you are allowed to write them as much as you like.

+16
source

char * str = "Shiv" gets a pointer to a string constant that can be loaded into a protected area of โ€‹โ€‹memory (for example, part of the executable code) that is only readable.

+4
source
 char *str = "Shiv"; 

It should be:

 const char *str = "Shiv"; 

And now you will have an error;)

+4
source

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 of this. This will allow you to read / write memory when using pointers. Using the [] notation allocates space on the stack directly, but the use of constant pointers fails.

+1
source

String literals are non-modifiable objects in both C and C ++. Attempting to modify a string literal always results in undefined behavior. This is exactly what you observe when you get a โ€œbus errorโ€ with

 char *str = "Shiv"; 

option. In this case, your reverse function will try to change the string literal. Therefore, the behavior is undefined.

 char str[] = "Shiv"; 
Option

will create a copy of the string literal in the modified array 'str', and then "reverse" will work with this copy. This will work fine.

PS Do not create pointers that do not contain constants for string literals. The first option was to be

 const char *str = "Shiv"; 

(pay attention to the additional "const").

+1
source

String literals (your "Shiv") are not changed.
You assign the address of such a string literal to the pointer, then you try to change the contents of the string literal by dereferencing the value of the pointer. This is 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 str element are changed.

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 can 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 tries to change such an array [string literal], the behavior is undefined.

+1
source

char * str - pointer / link to a block of characters (string). But it sits somewhere in the memory block, so you cannot just assign it that way.

0
source

Interestingly, I never noticed this. I was able to reproduce this condition in VS2008 C ++.

As a rule, it is a bad idea to modify constants in place.

In any case, this post explains this situation quite clearly.

The first (char []) is local data that you can edit (since the array is local data).

The second (char *) is a local pointer to global, static (persistent) data. You are not allowed to change the data constant.

If you have GNU C, you can compile with -fwritable-strings to keep the global string creation permanent, but this is not recommended.

0
source

All Articles