The code is self-explanatory, but it gives me segmentation fault, why? :\
#include <stdio.h>
int main(void)
{
char *c = "Hella";
*(c+4) = 'o';
printf("%s\n",c);
}
How to avoid it?
Don't modify a string literal!
char *c = "Hella";
Declares a pointer c to a string literal "Hella" stored in implementation defined read only memory.
You are not allowed to modify this literal. An attempt to do so results in Undefined Behavior.
You are lucky that your program crashes, an Undefined Behavior does not always result in a crash but may cause your program to behave weirdly in any possible way.
What you need here is an array:
char c[] = "Hella";
Good Read:
What is the difference between char a[] = ?string?; and char *p = ?string?;?
Put your string into an array allocated onto the stack:
char c[] = "Hella";
Because as said, string literals are usually read-only.
the way you create c it points to a string literal. You can not modify it's contents. If you want to be able to do that use:
char c[6] = "Hella";
c[4] = o;
Or use a dynamically allocated char array.
You are trying to overwrite a literal. Really your code should read:
const char *c = "Hella";
Which kinda explains what is going on.
To overwrite your own memory:
char c[] = "Hella";
is safer.
You can not modify strings that are defined in code. Use strdup if you want to modify them.
#include <stdio.h>
int main(void)
{
char *c = strdup("Hella");
*(c+4) = 'o';
printf("%s\n",c);
free(c);
}
Related
Why does this code produce an error? Shouldn't it output zbcde?
int main()
{
char *p="abcde";
*p='z';
printf("%s\n",p);
return 0;
}
You're trying to modify a string literal; it's undefined behavior.
Further explanation: "abcde" is not a char * but a const char *. You should do one of the following solutions:
char p[] = "abcde";
or
char *p = strdup("abcde");
(in the latter case, don't forget to free() p!)
char *p="abcde"; - This will keep the string abcde in text segement as read only data and the address will be kept in the local pointer variable p.
*p = 'z' will tries to replace the read only data a to z. Which is an undefined behaviour, which can leads to crash.
So declare the string as local char array variable as below.
char p[] = "abcde"
So allocate dynamic memory to keep the string like below.
char *p = strdup("abcde");
...
free(p);
Can I initialize string after declaration?
char *s;
s = "test";
instead of
char *s = "test";
You can, but keep in mind that with that statements you are storing in s a pointer to a read-only string allocated elsewhere. Any attempt to modify it will result in undefined behavior (i.e., on some compilers it may work, but often will just crash). That's why usually you use a const char * for that thing.
Yes, you can.
#include <stdio.h>
int
main(void)
{
// `s' is a pointer to `const char' because `s' may point to a string which
// is in read-only memory.
char const *s;
s = "hello";
puts(s);
return 0;
}
NB: It doesn't work with arrays.
#include <stdio.h>
int
main(void)
{
char s[32];
s = "hello"; // Syntax error.
puts(s);
return 0;
}
It is correct for pointers (as mentioned above) because the string inside quotes is allocated from the compiler at compile time, so you can point to this memory address. The problems comes when you try change its contents or when you have a fixed size array that want to point there
I am trying to understand why the following code is illegal:
int main ()
{
char *c = "hello";
c[3] = 'g'; // segmentation fault here
return 0;
}
What is the compiler doing when it encounters char *c = "hello";?
The way I understand it, its an automatic array of char, and c is a pointer to the first char. If so, c[3] is like *(c + 3) and I should be able to make the assignment.
Just trying to understand the way the compiler works.
String constants are immutable. You cannot change them, even if you assign them to a char * (so assign them to a const char * so you don't forget).
To go into some more detail, your code is roughly equivalent to:
int main() {
static const char ___internal_string[] = "hello";
char *c = (char *)___internal_string;
c[3] = 'g';
return 0;
}
This ___internal_string is often allocated to a read-only data segment - any attempt to change the data there results in a crash (strictly speaking, other results can happen as well - this is an example of 'undefined behavior'). Due to historical reasons, however, the compiler lets you assign to a char *, giving you the false impression that you can modify it.
Note that if you did this, it would work:
char c[] = "hello";
c[3] = 'g'; // ok
This is because we're initializing a non-const character array. Although the syntax looks similar, it is treated differently by the compiler.
there's a difference between these:
char c[] = "hello";
and
char *c = "hello";
In the first case the compiler allocates space on the stack for 6 bytes (i.e. 5 bytes for "hello" and one for the null-terminator.
In the second case the compiler generates a static const string called "hello" in a global area (aka a string literal, and allocates a pointer on the stack that is initialized to point to that const string.
You cannot modify a const string, and that's why you're getting a segfault.
You can't change the contents of a string literal. You need to make a copy.
#include <string.h>
int main ()
{
char *c = strdup("hello"); // Make a copy of "hello"
c[3] = 'g';
free(c);
return 0;
}
I have this program in C
#include<stdio.h>
int main()
{
printf("Hello New!\n");
char c = 'd';
char* s = "hello world";
char **t = &s;
*t[0] = c;
return 0;
}
The program compiles but doesn't run.
I have this output :
Hello New!
Bus error
I don't understand why
String constants are stored in readonly memory and you cannot modify them.
If you must, then use:
#include<stdio.h>
int main()
{
printf("Hello New!\n");
char c = 'd';
char s[] = "hello world";
char **t = &s[0];
*t[0] = c;
return 0;
}
This allocates a local variable (not a constant) that is conveniently initialized and may be modified to your heart's content.
You may not modify the string that 's' points to, in any way. It is in a part of memory that you are not allowed to change.
String constants are unmodifiable, despite having the type char* rather than const char* for historical reasons. Try using the string constant to initialize an array, rather than a pointer:
#include <stdio.h>
int
main(void)
{
char s[] = "hello new!";
puts(s);
s[0] = 'c';
puts(s);
return 0;
}
A bus error usually means that you're accessing a pointer with an invalid value - e.g. an address that is out of the address space.
I would guess that in this case, it is because you are trying to write to memory that is read-only. The string "hello world" is in a memory segment that you are not allowed to write to. Depending on the operating system, these memory segments are either protected or you can write arbitrary garbage to it. Seems like yours doesn't allow it. As you can see in the other answers, you can work around this by copying/initializing the string constant into an array.
The following code produces a segmentation fault on my system. I can't figure out why. Any help would be appreciated.
#include<stdio.h>
int main() {
char * a = "abc";
*a = 'c';
printf("%c\n", *a);
return 0;
}
The standard explicitly lists this as undefined behavior in §J.2:
— The program attempts to modify a
string literal (6.4.5)
If you want to copy it into a local array, do:
char a[] = "abc";
a is an array on the stack, and you can modify it freely.
Attempting to modify a string literal causes undefined behaviour.