Reputation: 1521
my code segfaults and I don't know why.
1 #include <stdio.h>
2
3 void overwrite(char str[], char x) {
4 int i;
5 for (i = 0; str[i] != '\0'; i++)
6 str[i] = x;
7 }
8
9 int main(void) {
10 char *s = "abcde";
11 char x = 'X';
12 overwrite(s, x);
13 printf("%s\n", s);
14 return 0;
15 }
The gdb debugger tells me, that problem is on the line 6, where I want to store a char, into c-string (if I use lvalue pointer dereferencing, it's the same problem.) This is what he says:
(gdb) run
Starting program: /tmp/x/x
Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5
5 for (i = 0; str[i] != '\0'; i++)
(gdb) s
6 str[i] = x;
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6
6 str[i] = x;
(gdb) q
I am learning from K&R-C book and this is simplified example from chapter 2.8 (the remove function). I have no idea where is the problem.
Upvotes: 3
Views: 1134
Reputation: 16178
because char*s = "abcde"; creates string in readonly memory. try
char s[] = "abcde";
EDIT: explanation: char* is pointer, and "abcde" is created in readonly memory -> immutable.
char[] is array, which is wholly stored on stack and initialized from the memory, so is mutable
Upvotes: 17
Reputation: 374
Try out:
#include <iostream>
#include <cstring>
using namespace std;
void overwrite(char[], char);
int main(void)
{
char *s = strdup("abcde");
char X = 'X';
overwrite(s, X);
cout << s << endl;
if(s!=NULL)
delete [] s;
return 0;
}
void overwrite(char str[], char x)
{
for(int i=0; str[i]!='\0'; i++)
str[i] = x;
}
Upvotes: -1
Reputation: 27492
Not disagreeing, but just to elaborate: Consider what would happen if the compiler allowed this. You could write:
char *s1="abcde";
char *s2="abcde";
s1[0]='x';
puts(s1);
puts(s2);
If the compiler recognizes that the two literals are the same and re-uses them, but then also allows line 3, your output would be:
xbcde
xbcde
Which is probably not what you would want. This would be particularly mysterious if the two literals were in widely-separated parts of the program.
Upvotes: 1
Reputation: 108978
When you define a pointer to a string literal, declare it as const char *
.
const char *s = "abcde";
That way, your compiler complains when you try to send that string to the overwrite() function.
const char *s = "abcde";
char t[] = "fghij";
char x = 'X';
overwrite(s, x); /* oops */
overwrite(t, x); /* ok */
Upvotes: 2
Reputation: 15935
my guess is the parameter definition where you define the type as an array of chars. While you are passing a pointer to a char
You could try changing the first line to this:
void overwrite(char *str, char x) {
A char array and a char pointer are not semantically the same.
Upvotes: -2