1

I am using strchr to find a point in the buffer where an = is encountered. Then I am changing that equal too character to a M. I get a segfault at the line where I try to do this.

This is the FULL code:

int main(void){
    char *buffer = "Name=Tom"
    char *pointer;
    pointer = strchr(buffer,'=');
    *pointer = 'M';    <--------- Segfault Occurs here
return (0);
}

I get the following error with the segfault:

Process terminating with default action of signal 11 (SIGSEGV)
 Bad permissions for mapperd region at addresss .....
John Doe
  • 45
  • 3
  • 2
    Please provide a [minimal complete and verifiable example](https://stackoverflow.com/help/mcve). You haven't even provided the definition and contents of `buffer` which is crucial to the question. For example, if `buffer` contains a string constant or does not contain any `=` characters then you would get a seg fault. But impossible to say with incomplete code like you have provided. – kaylum Feb 08 '16 at 22:13
  • 3
    Maybe the character '=' isn't found, and strchr returns NULL – Martín Muñoz del Río Feb 08 '16 at 22:14
  • Since this question seems to be designed as a guessing game, I'd suspect that you've declare buffer like so: `char *buffer="a buffer=something`, making it a constant literal value and read only. – David Hoelzer Feb 08 '16 at 22:41
  • @JohnDoe Now that you have finally added the code it is clear (as guessed by multiple people) that you are attempting to change a string literal. String literals are not writeable. Modify the `buffer` declaration to make it a char array instead: `char buffer[] = "Name=Tom";` – kaylum Feb 08 '16 at 22:46
  • @DavidHoelzer I added the full code. – John Doe Feb 08 '16 at 22:46
  • See [Why do I get a segmentation fault when writing to a string initialized with “char *s” but not “char s\[\]”?](http://stackoverflow.com/q/164194/176646) – ThisSuitIsBlackNot Feb 08 '16 at 23:11

3 Answers3

7

You are not checking the return value of strchr, it could be NULL since we don't see your input.

In addition to this, where and how is buffer declared? not all char* can be modified, since they could be stored in data segment of the binary (as a string literal).

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 1
    It is not NULL. I have added the error valgrind displays when the segfault happens. – John Doe Feb 08 '16 at 22:27
  • 2
    Then the cause is the second I pointed out. That literal is read only and it is stored in data segment, try with char[] buffer = "..". – Jack Feb 08 '16 at 22:48
4

You are attempting to modify the value of a string literal which will be stored in a read only memory segment. This results in an access violation.

The problem is here:

char *buffer = "Name=Tom";

Modify it to be:

char buffer[] = "Name=Tom";
David Hoelzer
  • 15,862
  • 4
  • 48
  • 67
  • The problem with this method, is that since you are not specifying the size of buffer, it is automatically set to the length of "Name=Tom" plus one for '\0'. So if you want to place a string which is longer than the current one, it will give an error. Refer to this old post http://stackoverflow.com/questions/6803387/why-can-a-string-be-assigned-to-a-char-pointer-but-not-to-a-char-array – Ratan Senapathy Feb 09 '16 at 06:14
  • 1
    @RatanSenapathy I think you're completely missing the point. I'm fully aware of how to allocate memory... The OP was unaware of where that memory was being allocated and why he couldn't write to it. – David Hoelzer Feb 09 '16 at 12:14
1

What you are doing here is wrong:

char *buffer = "Name=Tom";

When you assign a string literal to a pointer it is stored as a const char*, which cannot be modified, which is what you are trying to do later in your code.

Here, you first need to allocate memory to buffer and then use strcpy to copy the contents like:

char buffer[100];
strcpy(buffer, "Name=Tom");
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Ahmed Akhtar
  • 1,444
  • 1
  • 16
  • 28