0

Possible Duplicate:
Why do I get a segmentation fault when writing to a string?

I expect the output of this program to be: ibjgsjfoet But i am getting a segmentation fault.

#include <stdio.h>
int main()
{

    char *p="haifriends",*p1;
    p1=p;
    while(*p!='\0')
    ++*p++;
    printf("%s   %s",p,p1);
    return 0;

}
Community
  • 1
  • 1

6 Answers6

10

I expect the output of this program to be: ibjgsjfoet

char *p="haifriends",*p1;

haifriends resides in read only section of the memory and cannot be modified. If you wish to modify the string literal then you have to make a copy.

char p[]="haifriends",*p1;
p1 = p;
Mahesh
  • 34,573
  • 20
  • 89
  • 115
7

Using two autoincrements in the same statement is asking for trouble. Don't try to be tricky. Write your code so that it is clear and expressive, and you'll get much better results.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 1
    If he didn't use two increments in the same statement, he'd still be causing the segfault, so this "answer" is completely unrelated to the question. Style advice belongs in comments. – sepp2k Aug 05 '11 at 16:54
2

You are trying to modify a string literal:

char *p="haifriends";
++*p;

Usually, string literals are allocated in non writable memory, hence the segfault.

sergio
  • 68,819
  • 11
  • 102
  • 123
1

The memory region in which p lies cannot be written to. You can only modify memory you've malloced or which lies on the stack:

#include <stdio.h>
int main()
{
    char buffer[11];
    char *p,*p1;

    strcpy(buffer, "haifriends");
    p = &buffer[0];

    p1=p;
    while(*p!='\0')
    ++*p++;
    printf("%s   %s",p,p1);
    return 0;
}

This is in no way good practice but I hope this example code clarifies the issue.

Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
1

This will work:

#include <stdio.h>
int main()
{

    char p[11]="haifriends";
    char *p1;
    p1=p;
    while(*p1!='\0')
    ++*p1++;
    printf("%s   %s",p,p1);
    return 0;
}

Most compilers issue a warning on conversion from constant string to char*

Ragesh Chakkadath
  • 1,521
  • 1
  • 14
  • 32
  • That's not true, most compilers may *complain* about the conversion from string literal to `char *` but they will allow it. This is because string literals in C have type `char[N]` as opposed to `const char[N]` (where N is the length including NULL terminator) – Praetorian Aug 05 '11 at 15:02
  • Well, yes. you're right.. got the word wrong! Editing... – Ragesh Chakkadath Aug 05 '11 at 15:05
0

Try changing *p="haifriends" to p[]="haifriends". Iirc you aren't allowed to modify string literals that are assigned to a regular character pointer, but you are when they're assigned to an array of characters.

Also ++*p++; is undefined behavior. Try *p++;p++;, or maybe ++*(p++); if that wouldn't also be undefined behavior (pretty sure it would be, though).

According to Michael, ++*p++; isn't undefined behavior, but I would still recommend going with *p++;p++; or ++*(p++); for clarification, as he agrees on that being a good idea.

JAB
  • 20,783
  • 6
  • 71
  • 80
  • 4
    `*p += 2` is not the same as `++*p++`. – Linus Kleen Aug 05 '11 at 14:55
  • Oh, woops, I suppose you're right. fixed. ...Or are multiple increments in the same statement allowed when a variable is a pointer? Is `++*p++;` equivalent to `++*(p++);`? – JAB Aug 05 '11 at 15:00
  • 1
    @Linus No, but that's because ++*p++ means "crash and burn". It is undefined behavior, there is no logic translation for what it will do in the C language. – Lundin Aug 05 '11 at 15:20
  • @Lundin Yes, it's undefined. But still not that undefined so it would advance the pointer twice? – Linus Kleen Aug 05 '11 at 15:21
  • 1
    @Linus Oh that's perfectly fine. The program may do _anything_ when it encounters undefined behavior. – Lundin Aug 05 '11 at 15:28
  • @Linus: My replacement was meant for what user302520 actually intended to do, so it depended on if the line was supposed to be interpreted as `++(*p)++` or `++*(p++)`. The former implies the intent of incrementing by two, while the latter implies the intent of incrementing the value pointed to and then incrementing the value held by the pointer itself (which is, assumedly, what user302520 actually wants to do. I just had a mental glitch and thought it was the first case.) – JAB Aug 05 '11 at 15:29
  • 1
    `++*p++` is *not* undefined behavior because the operator precedence causes the sub-expressions expressions to bind like so: `++(*(p++))`. So there are two different things being modified - the 'pointee' by the prefix increment and the pointer by the postfix increment. That said, I think it's still a very poor expression to use since it's a bit of a puzzle figuring out. I think the advice of breaking it apart is good. – Michael Burr Aug 05 '11 at 16:09
  • @Michael: It's a puzzle itself. The problem was to interpret this puzzle. –  Aug 05 '11 at 20:08