-3

I am trying to write a program that converts a string to morse code. It currently works fine whenever input is a string literal but whenever I send a string as a variable I get a segmentation fault.

void morseCode(char* s)
{
    for (int i = 0; s[i]!='\0'; i++)
        printf("%s",morseEncode(s[i])); //morseEncode is a function which returns char* of morse code
}


int main()
{
    int length = strlen("Hello");
    char* s = (char*) malloc(length + 1);
    s = "Hello";

    morseCode(s);       // Segmentation fault
    morseCode("Hello"); // works fine
    return 0;
}
kopecs
  • 1,545
  • 10
  • 20
  • 3
    Could you also show `moreEncode`? As this is it isn't a [Minimum, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). – kopecs Dec 31 '19 at 02:16
  • 1
    Please post a [minimal verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). In particular, we need to see `morseEncode`. Also, suggest you run your program in a debugger. That is the best way for you to find the problem. – kaylum Dec 31 '19 at 02:16
  • Unrelated to your issue, but also take a look at [Do I cast the result of `malloc`?](https://stackoverflow.com/a/605858/12521158) – kopecs Dec 31 '19 at 02:17
  • 2
    `char* s =(char*) malloc(lenght+1); s = "Hello";` That isn't the correct way to copy a string into a char buffer. Use `strcpy`. As it is, the `malloc` memory is lost and a memory leak occurs. – kaylum Dec 31 '19 at 02:17
  • Does this answer your question? [Why do I get a segmentation fault when writing to a string initialized with "char \*s" but not "char s\[\]"?](https://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – kopecs Dec 31 '19 at 02:32

1 Answers1

1

This is a result of passing the variable s to morseEncode (which presumably modifies it) as modifying s is undefined behaviour. Specifically, modifying a string literal in such a manner is undefined behaviour per 6.4.5p6 [from C99:TC3]

It is unspecified whether these (string literal) arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

(text in parentheses added by me)

You might also want to take a look at this question.

You could instead declare s like so (with automatic storage duration).

char s[] = "Hello";

If you need s to be a pointer you could try

// Yes, sizeof(char) will always be 1 and you could remove it.
char *s = malloc(sizeof(char) * (strlen("Hello") + 1)); 
strcpy(s, "Hello");

// Your code that uses s here

free(s) // Important!

As an additional note @kaylum has pointed out that the original answer didn't provide a justification as to why calling the function in the two different ways produced different results. This is because the undefined behaviour you're running into just so happened to be undefined in a different way for each call. If I write out a similar program and compile it using gcc (with no flags) I end up running into a segfault both ways; on the other hand, compiling with clang -O both work! Its simply a product of whatever segment(s) of memory your specific compiler has decided you place each of those sequences of characters.

kopecs
  • 1,545
  • 10
  • 20
  • OP claims `morseCode(s)` causes a seg fault but `morseCode("Hello")` does not. Your answer does not seem to address that point clearly. – kaylum Dec 31 '19 at 02:35
  • @kaylum I'd hazard a guess that it's some compiler specific behaviour; both are undefined, the compiler OP is using might just happen to put literals in read only memory when they aren't used to initialise `char*`s or something similar. The fact that its undefined *does* in fact address that inconsistency. I'd agree that without OP disclosing what compiler targeting what system they're using (or providing the source of `morseEncode`) why that behaviour is different is impossible to diagnose perfectly, but the fact that they're different doesn't make one any more well defined. – kopecs Dec 31 '19 at 02:41
  • I agree. I'm just pointing out your answer doesn't clearly/explicitly explain the apparent difference in behaviour that the OP has observed. – kaylum Dec 31 '19 at 02:43
  • @kaylum I figured pointing it out as undefined behaviour would encompass enough, but I've added an addendum now! – kopecs Dec 31 '19 at 02:47