-1

I have a char pointer and i give it a value. In a next step i want to change the first letter.

#include <stdio.h>
#include <stdlib.h>

void main() {
    char * str;
    str = (char*)malloc(4);
    str = "abc";
    printf("%s\n", str); //output: abc
    *str = 'c';          //segmentation fault
    printf("%s\n", str); //here i would like to have output cbc
}

Why does it not work?

lurker
  • 56,987
  • 9
  • 69
  • 103
Karl
  • 63
  • 6

3 Answers3

4

when you assign "abc" to str, it doesn't copy "abc" to the newly allocated memory. Instead str now points to readonly memory where the constant "abc" is stored.

You get a segmentation fault because you try to write to read-only memory.

instead of

str = "abc";

try

str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
str[3] = '\0';
  • 1
    Ok. I'll use arrays instead of pointers. Thanks. – Karl Jun 22 '19 at 14:16
  • 1
    Now i found this answer also:https://stackoverflow.com/questions/22103212/changing-chars-in-char-pointer-variable?rq=1 – Karl Jun 22 '19 at 14:20
2

There are few issues in the code. Firstly, here

str = (char*)malloc(4); /* dynamic memory i.e str points to heap section */
str = "abc"; /* str now points to ready only memory i.e string constants */

you are overwriting dynamically allocated memory with string literal "abc" memory i.e its a memory leak as str no longer points to dynamic memory.

To avoid all these issues either create a local character array, not dynamic one and then change the str[0]. For e.g

char str[4] = "abc";
*str = 'c';

Or use memcpy() if you want to do first mallco() and then copey abc into that. For e.g

int main(void) {
    char *str = malloc(4); /* Don't use magic number like 4, use MACRO instead */
    if(str == NULL) {
        /* @TODO Error Handling of malloc failure */
    }
    memcpy(str, "abc",sizeof("abc"));
    printf("%s\n", str); 
    *str = 'c';          
    printf("%s\n", str); 
    /* free dynamic memory */
    return 0;
}
Achal
  • 11,821
  • 2
  • 15
  • 37
1

How to assign value to a pointer?

With one of the assignment operators, of course. Typically the simple assignment operator (=), but plussignment (+=) and minussignment (-=) can also be used under some circumstances.

I have a char pointer and i give it a value.

In fact, you give it two different values, one after the other. First, with

    str = (char*)malloc(4);

you give it a value that points to your four-byte dynamically allocated space. Note that the cast is unnecessary in C and considered poor style by many.

Then, with

   str = "abc";

, you assign it a different value, losing the previous one and therefore leaking memory. You are assigning a value to the pointer, not modifying the data to which it points.

You have several alternatives for modifying the pointed-to memory.

  • You can assign directly via the pointer and related ones (not forgetting the string terrminator!):

    *str = 'a';
    *(str + 1) = 'b';
    // etc.
    
  • Equivalently to the previous, you can use indexing syntax

    str[0] = 'a';
    str[1] = 'b';
    // etc.
    
  • You can perform a block copy with the memcpy() or memmove() function:

    memcpy(str, "abc", 4);
    
  • For C strings in particular, such as yours, there are functions specific to this purpose, the common being strcpy():

    strcpy(str, "abc");
    

    Note that strcpy expects the source to be null terminated, which all string literals are, but some other character arrays are not.

In a next step i want to change the first letter.

Your syntax is correct for that, but you may not modify a string literal. That's what your original code is trying to do, because that's your second assignment causes str to point to the literal "abc".

Overall, do not confuse a pointer with the object to which it points.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157