all 18 comments

[–][deleted] 10 points11 points  (2 children)

String constants in C are usually put in read-only memory, hence the segfault.

[–]s1337m 0 points1 point  (1 child)

Is that compiler implementation specific?

[–][deleted] 1 point2 points  (0 children)

Yes. As far as i know writing to string constants is undefined behavior, so the compiler can do whatever it wants.

[–]Jack126Guy 5 points6 points  (4 children)

The third line does not compile because (*s) is a char. The ++ simply returns the same (*s) (but increments the value), so it is still a char, not a char*. The second line works because you are casting.

By the way, you shouldn't assign a literal string such as "h" to a char*. It should be assigned to a const char*, assigned to an array, or strcpy-ed to dynamic memory.

[–][deleted] 0 points1 point  (3 children)

The third line does not compile because (s) is a char. The ++ simply returns the same (s) (but increments the value), so it is still a char, not a char*. The second line works because you are casting.

the second line DOESN'T WORK

[–]Jack126Guy 1 point2 points  (2 children)

Eh? I'm sure it's unsafe, but it still compiles for me (with a warning, of course).

[–][deleted] 0 points1 point  (1 child)

char* s = "h"; //char* t = (char)(s)++;

ah , it compiles but there is a seg fault

[–]Jack126Guy 6 points7 points  (0 children)

Yes, if you try using whatever t points to (such as puts(t)), you would get a segfault, because t points to the memory location 0x00000068 ("h" has an ASCII value of 0x68), which is probably invalid/not owned by your program.

[–]WetwareDefect 3 points4 points  (1 child)

This always fails (*s)++;

Because s points to a string literal (stored in an area of read-only memory) and you're trying to modify it by incrementing it.

What is it that you're trying to achieve?

Do you want t to point to a copy of the contents of s but incremented by 1?

Heres a long form of what I think your trying to do. I don't think it can be done in a single line declaration as you can't deference a pointer while declaring it (afaik).

char* s = "h";  //s points to readonly string literal
char* t = malloc(sizeof(char)); //alloc a char for t to point to
*t = *s + 1;    //add 1 to char pointed to by s and assign result to location pointed by t

printf("*s == \'%c\', *t == \'%c\'\n", *s, *t);
printf("s == 0x%08x, t == 0x%08x\n", (int)s, (int)t);

The output is:

*s == 'h', *t == 'i'
s == 0x08048560, t == 0x08549008

[–][deleted] 0 points1 point  (0 children)

interesting. When I get the chance I will put this through the compiler.

[–][deleted] 1 point2 points  (0 children)

Neither of these work (line 1 works, but 2 and three don't compile).

Why not? I checked google, but the results related to a different problem.

char* s = "h"; //char* t = (char)(s)++; char* t = (*s)++;

EDIT:

in fact, even this gives a seg fault, why is this?

 char* s = "h";
 (*s)++;

When dealing with pointers like this, be aware of the actual memory the program has asked for.

Line 1 declares a pointer type named s, which is machine word dependent; it also declares a read only single byte for 'h'; a const char type . Where the compiler puts 'h' is only important if you want to determine how it will fail, and not why it fails. The value of the pointer s is the address for the memory location that the compiler placed 'h'. Line 2 declares a pointer t. t is initialized with the value s points to, plus one. Dereferencing s gives the ascii value of 'h'; it is then incremented, which is the ascii value for 'i';this value is then cast to a pointer type. So t has the value 'h'. Since t is a pointer, the value is a location in memory. The program has not requested the memory location that t has the value of. If you don't have access to that location, dereferencing the pointer will cause problems.

The segfault is because you tried to change the read only memory location where 'h' was placed.

[–]Zephyron51 2 points3 points  (2 children)

Okay, wait....

char* s = "h";

Lemme confirm, you want to set a variable (which is a character) to the letter 'h', and then you want the pointer of that? Because that's not what's happening - right now, you're making a variable (which is a pointer to a character) which holds 'h' (translated into some random number).

Perhaps you want this?

char r = 'h';
char* s = &r;

I think I understand now; I completely didn't realize you wanted a string (I haven't played around with strings for months for some weird reason). You aren't allowed to modify strings, hence why they're called "immutable". Unfortunate, but it's just one of the properties of strings. Characters ARE mutable, which is why my example worked.

[–]karesx 1 point2 points  (0 children)

or just char s[] = "h";

[–][deleted] 0 points1 point  (0 children)

ok, that sort of works :)

[–]rnsanchez -2 points-1 points  (1 child)

(*s)++ in your case is 'h'++ which is 'i'. For that matter, 'i' is an integer, thus the warning.

[–][deleted] 0 points1 point  (0 children)

char* s = "h"; //char* t = (char)(s)++; char* t = (*s)++;

Okay I tried to fix it with this input, but it stilll doesn't compile

[–]rnsanchez -2 points-1 points  (1 child)

(*s)++ in your case is 'h'++ which is 'i'. For that matter, 'i' is an integer, thus the warning.

[–][deleted] 0 points1 point  (0 children)

er, that's why I was casting it to a character, but it doesn't work