I heard that in C, if I do
char *s = "hello world".
the "hello world" is actually stored in read-only memory.
I am not so clear about read-only memory. What is the explanation? Is that like a flag to the compiler that tells the compiler to do not write into that section?
That's not a feature of the C language but a feature of the compiler/linker and the operating system working together.
When you compile such code the following happens:
The compiler will put the string into a read-only data-section.
The linker collects all the data in such read-only sections and puts them into a single segment. This segment resides in the executable file and is flagged with a "read only"-attribute.
Now comes the operating system executable loader. It loads the executable (or maps it into memory to be more exact). Once this is done, the loader walks the sections and sets access-permissions for each segment. For a read-only data segment it will most likely disable code-execute and write access. Code (for example, your functions) gets execute rights but no write access. Ordinary data like static variables gets read and write access and so on...
That's how modern operating systems do it.
As said, it's not a feature of the C language. If you compile the same problem for DOS, for example, the program will run but no write protection would be possible, because the DOS-loader does not know about read-only sections.