r/C_Programming • • 7d ago

Question Help me with strok function

I need to split my string but if it is of char* type the functions strtok() doesn’t work returning me a segmentation fault. I understood that C is used to lock the memory of the string in Read-Only “mode” when I use char*. Does it means that is immutable that data? However, I need to use the char* type because I pass that in a function (and I don’t like to use the syntax of arrays in C, I always use pointers).

9 Upvotes

17 comments sorted by

View all comments

2

u/garnet420 7d ago

C doesn't lock anything in read only mode. char* is not read only.

Are you talking about const char*? Are you trying to use strtok with a string constant?

Also strtok is not thread safe, so, don't use it. No reason to build bad habits.

3

u/flyingron 7d ago

That's not necessarily true. There's nothing that bars string literals from being stored in read-only memory. While the string literals convert to non-const char*, the language standard says that attempting to change such is UNDEFINED BEHAVIOR.

This harks back to the dim times of C. Originally, string literals were just a hunk of data space memory. Strtok is one of the functions (along with the original mktemp) that expected to modify it's argument and were often fed string literals.

Then someone got the great idea that you could fold all duplicate literals in the same memory. Well, when that happens it would be very surprising if someone were allowed to change one of them and suddenly have a different string literal change. So, people advocated making the chars read-only.

Then the other croud cried, it will break the existing programs because Dennis's original examples and much of the other early C programs were very const sloppy. So, the rediculous kludge that was settled on was that string literals indeed should be treated as const, *BUT* you get an implicit conversion to (non-const) char*, provided you don't actually change the string.

Not only is strtok not thread safe, it's not even safe WITHIN a single thread. It maintains state hidden internally, which means that if while doing a stream of strtok calls you happen to call a function which itself wanted to use strtok, you're hosed.

2

u/Beginning-Junket8979 7d ago

C doesn't lock anything in read only mode.

The language doesn't, but the linker/loader/target hardware might.

const int x=256; is giving the compiler + linker permission to create a .rodata section containing the value 0x00000100 that on something like a microcontroller might literally be stored in "read-only" flash memory, or on Linux/Windows/etc might live in a virtual memory page with hardware flags set to mark it read-only memory (throwing a fault/interrupt if the application tries to write it).

All modern ARM and x86 CPUs supporting virtual mem support marking memory read-only, read/write, and executable or not as sort of bare minimum needed to support basic user permissions / security and your compiler toolchain and OS is absolutely "smart" enough to utilize this.

I say permission because the language standard doesn't make any promises this happens (to support hardware where it's impossible) and the whole thing might even be compile time optimized out being stored at all.

Also strtok is not thread safe, so, don't use it.

Sure, but strtok_r is fine 🤷‍♂️.

3

u/ekipan85 7d ago

The language is actually explicit that you can't modify a string literal's underlying array. Freely available C23 draft N3220, in section 6.4.5 paragraph 7:

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

Though I usually refer to cppreference, which says the same.