Pointers and Strings causing segmentation fault [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between char a[] = “string”; and char *p = “string”;
char *str = "Hello";
printf("%c",++*str);
This gives segmentation fault on linux with gcc.
The moment the first statement is changes to as
char str[10] = "Hello";
It works. What may be the reason?

It is undefined behaviour to attempt to modify a string literal.
The compiler is free to place it in read-only memory (as it probably does in your case). Attempting to modify read-only memory is what's probably triggering the segfault.

This statement char *str = "Hello"; stores the string "Hello" in RO-section and assigns the address of the area of RO-section(in which "Hello"is stored) to str. The data stored in RO-section cannot be modified thus you are getting a segfault.
char str[10] = "Hello";
is also wrong. You should instead write
char str[10];
strncpy(str,"Hello",sizeof(str));

Related

Bus error 10 in C: string literals [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 7 years ago.
Can someone explain why
char *s1 = "abcd";
char *s2 = s1;
s1[0] = "z";
s1[2] = "\0";
gives me a bus error 10 BUT
char s1[] = "abcd";
char *s2 = s1;
s1[0] = "z";
s1[2] = "\0";
doesn't?
are char *s1 and char s1[] not equivalent? Please explain, thanks.
Be free (of historical lazyness), be wise! Pointers are not arrays! Tutorials have lied you!
In the first example, you're modifying a pointer to a constant string literal, and that's undefined behaviour. Anything can happen then!
Meanwhile, in the second case, the string itself is stored inside the array, and the array itself is in the stack. Thus, the second example exposes more than a plain innocent array that's modifiable.
The s2 pointers make no difference in all this. IMHO, the fact that the first case is compilable is just historical lazyness, otherwise known as backwards compatibility.
BTW: Are you assigning string literals to chars? That's undefined behaviour too!
In the first case you set a s1 pointer to the address const string. Const string are stored in read -only area and you cannot modify it. This means that you cannot modify a character s[x]. It is UB
In the second case you declare a local array inited with a string. In this case only the init value is read-only and after init you use an allocated array that can be modified.

Segmentation Fault while using tolower() on dynamic arrays [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 8 years ago.
I put this code on my C compiler (Dev Cpp).
char *str = "SomeTHing";
for(int i = 0; str[i]; i++){
str[i] = tolower(str[i]);
}
This gives a segmentation fault whereas if i use a static array,
char str[10] = "SomeTHing";
the loop works fine. Can anyone tell why is this happening?
char *str = "SomeTHing"; allocates read-only memory to the pointer str. To change its contents in any way is undefined behaviour. On your system that is manifesting itself as a crash. It's a pity that (i) your compiler is not warning you about your assigning this to a char* rather than a const char* or (ii) you're ignoring the warning.
char str[10] = "SomeTHing"; allocates the buffer on the stack, including the null terminator. Changing its contents is defined, although you need to keep a null terminator intact if you want to use some of the string library functions like strlen that rely on it.
char *str = "SomeTHing";
will place SomeTHing in the read-only parts of the memory and making str a pointer to that, making any writing operation on this memory illegal. Any try to modification this cause Undefined Behaviour.
Now following case
char str[10] = "SomeTHing";
this is working because puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. it will probably be stored within an "initialized data segment" that is loaded from the executable file into write able memory when the program is run.

Segmentation Fault related to Pointer in c [duplicate]

This question already has answers here:
Segmentation fault with strcpy() [duplicate]
(7 answers)
Closed 9 years ago.
int main()
{
char *s="Hello";
*s="World";
printf("%s\n",s);
}
Why does the above program result in a segmentation fault?
int main()
{
char *s="Hello"; // makes 's' point to a constant
*s="World"; // modifies what 's' points to
printf("%s\n",s);
}
The first line of code makes s point to a constant. The second line tries to modify what s points to. So you are trying to modify a constant, which you can't do because a constant is ... well ... constant.
because *s is a char not a char*(string)
char *s="Hello";
declares a pointer to a string literal "Hello". This may exist in read-only memory so the line
*s="World";
is results in undefined behaviour. A crash is a valid (and useful) form of undefined behaviour.
Either of the following alternatives would work
const char* s = "Hello";
s="World";
printf("%s\n",s);
char s[16] = "Hello";
strcpy(s, "World";)
printf("%s\n",s);
s points to static (global) memory when it is created. You cannot reassign to that memory at run-time, hence, the crash.
*s is the first char of the string, so assigning string to character makes error.
If you want to assing string use s = "world"
int main()
{
char *s="Hello";
s="World";
printf("%s\n",s);
}
now try it will work.
char *s="hello"; Here s is in readonly location. So we can assign another string, but cannot rewrite new string.
s = "hello"; //work
strcpy(s, "hello"); //segmentation fault
There are two problems here.
The statement
*s = "World";
dereferences s, which gives you the first character of the string "Hello", or 'H'. So you're trying to assign a pointer value (the address of the string "World") to a single char object (the first character of the "Hello" string literal).
But...
On some systems (such as yours, apparently), string literals are stored in a read-only data segment, and attempting to modify read-only memory will lead to a runtime error on some systems. Hence the crash.
To change s to point to the "World" string literal, simply drop the dereference:
s = "World";
*s is the same as s[0]. s[0] has room to store a single character; in this case a 'W'.
There's not room to store the location of "World" in that character.
That's why you're getting a segmentation fault.

Confusion in basic concept of pointers and strings [duplicate]

This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 9 years ago.
In my GCC 32-bit compiler, the following code gives the output
char *str1="United";
printf("%s",str1);
output:
United
then should I consider char *str1="United"; the same as char str1[]="United"?
The two are not the same: char *str1="United" gives you a pointer to a literal string, which must not be modified (else it's undefined behavior). The type of a literal string should really be const but it's non-const for historical reasons. On the other hand, char str1[]="United" gives you a modifiable local string.
char* str = "United"; is read-only. You wouldn't be able to reach inside the string and change parts of it:
*str = 'A';
Will most likely give you a segmentation fault.
On the other hand char str1[] = "United"; is an array and so it can be modified as long as you don't exceed the space allocated for it (arrays cannot be resized). For example this is perfectly legal:
char str[] = "United";
str[0] = 'A';
printf("%s\n", str);
This will print Anited.
See the comp.lang.c.faq, question 1.32. It basically boils down to the fact that declaring the string in array form (char str[] = "foo") is identical to char str[] = {'f','o','o'}, which is identical to char str[] = {102, 111, 111}; that is, it is a normal array on the stack. But when you use a string literal in any other context it becomes "an unnamed, static array of characters, [which] may be stored in read-only memory, and which therefore cannot necessarily be modified." (And trying to modify it results in undefined behavior wherever it happens to be stored, so don't).

Initializing a string in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between char *str=“STRING” and char str[] = “STRING”?
I wrote the following code:
int main()
{
char *str = "hello";
str[0] = 'H';
printf("%s\n", str);
}
This gives me a segmentation fault, I cant understand why.
str is pointer to char not const char. Even if that's the case shouldn't it give a compile error like the following program:
int main()
{
const char *str = "hello";
str[0] = 'H';
printf("%s\n", str);
}
It gives an error: assignment of read-only location *str.
EDIT
If my code places the pointer to a read only location, shouldn't I get a compilation error?
You assign a pointer to a constant string (which comes as a part of your text and is thus not writable memory).
Fix with char str[] = "hello"; this will create a r/w copy of the constant string on your stack.
What you do is a perfectly valid pointer assignment. What the compiler does not know is that in a standard system constant strings are placed in read-only memory. On embedded (or other weird) systems this may be different.
Depending on your system you could come with an mprotect and change the VM flags on your pointer destination to writable. So the compiler allows for this code, your OS does not though.
When you initialize a char * using a literal string, then you shouldn't try to modify it's contents: the variable is pointing to memory that doesn't belong to you.
You can use:
char str[] = "hello";
str[0] = 'H';
With this code you've declared an array which is initialized with a copy of the literal string's contents, and now you can modify the array.
Your code has undefined behavior in runtime. You are attempting to write to a literal string, which is not allowed. Such writes may trigger an error or have undefined behavior. Your specific C compiler has str point to read-only memory, and attempting to write to that memory leads to a segmentation fault. Even though it's not const, the write is still not allowed.
char *str = "hello";
When you declare str as above, it is not guaranteed which part of memory it will be stored. str might be read-only depending on implementation. So trying to change it will cause segmentation fault.
In order to avoid segmentation faullt, declare str as an array of characters instead.
char *str = "hello";
here the string hello is a literal.
string literals are always stored in read only memory.
this is the reason you are getting a segmentation fault when you are trying to change the value at read only memory.
Declaring str as char* reserves memory for the pointer, but not for the string.
The compiler can put the memory for "hello" anywhere he likes.
You have no guarantee that str[i] is writable, so that's why in some compilers this results in a seg fault.
If you want to make sure that the string is in writable memory, then you have to allocate memory using alloc() or you can use
char str[] = "hello";

Resources