1

I have a simple C program as follows:

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

void convertToUpperCase(char* sPtr);

int main(int argc, char** argv) {
    char myString[] = "cHaRacTerS aND $32.95";
    char* anotherString = "cHaRacTerS aND $32.95";
    
    convertToUpperCase(myString); // THIS IS OK!
    convertToUpperCase(anotherString); // THIS CAUSES RUNTIME ERROR 
                                       // (ie. build success but run fail)!

    return (EXIT_SUCCESS);
}

void convertToUpperCase(char* sPtr) {
    while (*sPtr != '\0') { // current character is not null (ie. end of string).
        *sPtr = toupper(*sPtr); // turns valid characters into upper case
        ++sPtr; // point to next character within the string.
    }
}

It seems like passing anotherString into the function that expects a char* is the problem. From my understanding, both myString and anotherString are char* in C.

It seems to me the problem is how they are defined. For myString I defined it as an array of characters with a null terminator at the end. For anotherString it is a character pointer to a string literal somewhere.

But I can't figure out why the way they are defined matters in this situation.

Thanks in advance :)

edit: used specific terms as suggested by answers.

REN
  • 65
  • 6

1 Answers1

4

Because when you declare a literal, it is read only.

char myString[] = "cHaRacTerS aND $32.95"; // readwrite memory
char* anotherString = "cHaRacTerS aND $32.95"; // placed in readonly memory

Edit: to clarify, it is not only read-only, it is UB to write to a string literal. Thanks for that comment, @chux-reinstate-monica

AndersK
  • 35,813
  • 6
  • 60
  • 86