const char*与字符串字面量使用差异:Linux下Modbus串口连接异常排查
modbus_new_rtu Fails with a Character Array on Linux (But Works on Windows) Hey there, let's break down why you're hitting this issue—it's all about C-style string termination!
First, a quick recap of how C handles strings: any function expecting a const char* parameter assumes the string ends with a null character ('\0'). When you pass the string literal "/dev/ttyS4", the compiler automatically adds this null terminator behind the scenes. That's why this approach works flawlessly.
But when you define your array like this:
const char mbPort[] = {'/', 'd', 'e', 'v', '/', 't', 't', 'y', 'S', '4'};
You're creating an array exactly 10 characters long—with no null terminator at the end. When modbus_new_rtu tries to read this "string", it keeps scanning past the end of your array until it hits a random null byte in memory. On Linux, this almost certainly results in a garbage serial port path the system can't recognize—hence the connection failure.
Now, why does this work on Windows? It's pure luck. Your Windows array:
const char mbPort[] = { '\\', '\\', '.', '\\', '\\', 'C', 'O', 'M', '5' };
Is 9 characters long. By chance, the memory immediately after this array in your Windows program might happen to be a null byte. This isn't guaranteed though—your Windows code could break unexpectedly if your code changes or memory layout shifts.
Fixes to Try
There are two simple, reliable ways to fix this on Linux (and make your Windows code more robust too):
Add the null terminator explicitly to your array:
const char mbPort[] = {'/', 'd', 'e', 'v', '/', 't', 't', 'y', 'S', '4', '\0'};Initialize the array with a string literal (the easiest and most readable option):
const char mbPort[] = "/dev/ttyS4";This behaves exactly like passing the literal directly—the compiler automatically appends the required
'\0'for you.
Quick Verification
If you want to confirm this is the root cause, use strlen() to check the length of both versions:
- For the literal or properly terminated array:
strlen(mbPort)will return 10 (the correct length of "/dev/ttyS4"). - For your original array without
'\0':strlen(mbPort)will return a random number longer than 10, since it's reading past the array bounds.
This is a classic C string gotcha—easy to overlook, but once you know about null terminators, it all clicks into place.
内容的提问来源于stack exchange,提问作者Ksawery

