1

Good day,

I have a function ft_strupcase which takes in a char*, upper-cases it, and returns the parameter. The issue arose during the testing, namely using the function in a main. The following program results in a segmentation fault:

    int main()
    {
        char *hey = "hEy";
        printf("%s\n", ft_strupcase(hey));
    }

whereas this variation doesn't:

    int main()
    {
        char hey[] = "hEy";
        printf("%s\n", ft_strupcase(hey));
    }

Isn't *str and str[] the same? Doesn't str[i] = *(str + i)? Why do I encounter a segfault then?

Mampac
  • 194
  • 2
  • 13
  • 1
    Please see [Why can't I write to a string literal while I *can* write to a string object?](https://stackoverflow.com/questions/8718740/why-cant-i-write-to-a-string-literal-while-i-can-write-to-a-string-object) – Weather Vane Jun 09 '21 at 19:44
  • Please see [Why can I not modify a string literal in c?](https://stackoverflow.com/questions/58584310/why-can-i-not-modify-a-string-literal-in-c) and many others. – Weather Vane Jun 09 '21 at 19:46

1 Answers1

1
int main()
{
    char *hey = "hEy";
    printf("%s\n", ft_strupcase(hey));
}

In this code, hey points to a string literal, which is a constant. Then ft_strupcase modifies the thing you pass it a pointer to. So this code attempts to modify a constant.

You can't modify a constant. That's what it means for something to be constant.

int main()
{
    char hey[] = "hEy";
    printf("%s\n", ft_strupcase(hey));
}

Here, hey is an array of characters, initialized from a constant. The array is modifiable since the array entries are not constants.

If you have int i = 3;, you can modify i, but you can't modify the 3. The first code tries to modify the thing on the right side of the = by passing a function that modifies the thing pointed to a pointer to it. The second code modifies the thing on the left side of the =, which is perfectly legal.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    This answer should be made sticky, cos the there are so many beginner irritations, that make the mistake, to assume that initializing a char* with a string is the same as an assignment. So the simple rule is, if you later want to change the string, use an array, otherwise you can use a pointer to the string literal. Ideally make the pointer const. –  Jun 09 '21 at 19:51
  • 1
    @wired there is an old answer. Very frequent dupe. I would not answer it again – 0___________ Jun 09 '21 at 20:00
  • one thing I noticed is that segmentation fault appears only in functions that attempt to modify a string in some way; any other function that just reads from inside works perfectly fine with *-initialized strings. thank you so much for the clarification! – Mampac Jun 10 '21 at 06:39
  • question: had I malloc'd enough memory (4 bytes) for `hey`, then assigned the "hEy" to the pointer, would've the problem be resolved? – Mampac Jun 10 '21 at 06:53
  • @Mampac It depends what you mean by "then assigned the 'hEy' to the pointer". If you mean `hey = malloc(4); hey = "hEy";` then no, you just leaked the pointer you `malloc`ed. If you mean `hey = malloc(4); strcpy(hey, "hEy");` then yes, because you *copied* the constant's *value* into something modifiable, then modified the copy. – David Schwartz Jun 10 '21 at 16:30