0
#include <stdio.h>

char    *ft_strupcase(char *str);

char    *ft_strupcase(char *str)
{
    int i;

    i = 0;
    while (str[i])
    {
        if (str[i] >= 'a' && str[i] <= 'z')
        {
             str[i] -= 32;
        }
        i++;
    }
    return (str);
}

int main(void)
{
    char *test = ft_strupcase("fdfFEhk");
    for (int k = 0; test[k] != '\0'; k++)
    {
        printf("%c", test[k]);
    }
    return (0);
}

The expected result is to print the string passed to the function, all in capital letters. Instead, I get a bus error. Why and how can I fix this?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • You can't do it with a string literal. See here https://stackoverflow.com/questions/1614723/why-is-this-string-reversal-c-code-causing-a-segmentation-fault – Federico klez Culloca Jul 04 '17 at 07:52
  • You cannot modify a constant ... – Sir Jo Black Jul 04 '17 at 08:12
  • If you executes this program with a debugger you will discover that the instruction `str[i] -= 32;` will raise a segmentation fault at the first while loop cycle. This is 'cause the string `"fdfFEhk"` is a CONSTANT. Under the operating systems such as Linux or Windows this is an error. If you use this code under DOS it should run. – Sir Jo Black Jul 04 '17 at 08:16
  • It is the [same problem](https://stackoverflow.com/questions/44856233/why-is-this-c-code-getting-a-bus-error-no-external-functions-allowed). Why don't you read those answer? – BLUEPIXY Jul 04 '17 at 13:38

2 Answers2

3

In your ft_strupcase() function, you're trying to modify the content of a string literal. This causes undefined behavior.

To quote the standard, C11, chapter §6.4.5/P7, String literals

[...] If the program attempts to modify such an array, the behavior is undefined.

The argument you received is a string literal and you are not allowed to change the content. To avoid, you have to either

  • Pass a modifiable memory as the actual argument.
  • Inside the function, create a block (need to take care of the lifetime, either static storage or allocated via memory allocator functions), copy the content, perform the modify operations and return the address.
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • If you executes this program with a debugger you will discover that the instruction str[i] -= 32; will raise a segmentation fault at the first while loop cycle. This is 'cause the string "fdfFEhk" is a CONSTANT. Under the operating systems such as Linux or Windows this is an error. If you use this code under DOS it should run. – Sir Jo Black Jul 04 '17 at 08:18
  • 1
    @SergioFormiggini that's why it is undefined behaviour. Sometimes works, sometimes not. – unalignedmemoryaccess Jul 04 '17 at 08:21
  • 1
    @SergioFormiggini-- [The Standard explicitly states that it is undefined behavior to attempt to modify the contents of the array representing a string literal.](http://port70.net/~nsz/c/c11/n1570.html#6.4.5p7) – ad absurdum Jul 04 '17 at 08:27
  • @tilz0R Thanks for the follow up, I've added the reference into my answer. :) – Sourav Ghosh Jul 04 '17 at 09:00
1

This is undefined behaviour as you are modifying string literal using ft_strupcase function

Rewrite your code to:

char source[] = "fdfFEhk";
char *test = ft_strupcase(source);

Now your string is not string literal anymore and is copied to RAM everytime source variable is initialized. Therefore, you have defined behaviour.

unalignedmemoryaccess
  • 7,246
  • 2
  • 25
  • 40
  • In the code written by @EatABagel the problem is that the string he uses is a costant, not an UB (IMHO). – Sir Jo Black Jul 04 '17 at 08:20
  • @SergioFormiggini Trying to modify a constant is by definition undefined behaviour. – unalignedmemoryaccess Jul 04 '17 at 08:21
  • Under DOS it was possible. I'm just searching the old DOS compiler to see if it generates error, but is archeology!!! I think that is not undefined, but SO related. BTW is not a good style to modify constants. – Sir Jo Black Jul 04 '17 at 08:29
  • 1
    @SergioFormiggini still, undefined behaviour. Period. – unalignedmemoryaccess Jul 04 '17 at 08:29
  • The error is generated by the CPU that doesn't accept you write on memory area declared read-only. This behaviour doesn't depend by the C-Language. – Sir Jo Black Jul 04 '17 at 08:30
  • @SergioFormiggini Im done talking here, sorry. – unalignedmemoryaccess Jul 04 '17 at 08:31
  • @SergioFormiggini-- it _is_ undefined behavior [according to the Standard](http://port70.net/~nsz/c/c11/n1570.html#6.4.5p7), which is the final word on the matter. That it appears to work may be a manifestation of UB; this is not proof that it is not UB. But, Microsoft is notoriously noncomformant. – ad absurdum Jul 04 '17 at 08:34