C语言客户端-服务器Socket读取char*时触发Segmentation Fault
Hey there! Let's dig into that segmentation fault you're hitting in your receiveTimeResponse function. Segfaults with structs containing pointers are super common when dealing with network IPC, so let's break down the likely issues and fixes.
Core Problem: Pointers Don't Travel Over the Network
First off, the biggest red flag here is the char* date field in your timeStructResponse struct. When you send this struct over the network, you're only sending the memory address stored in the date pointer—not the actual string data it points to.
On the server side, that pointer points to valid memory where the time string lives. But when your client receives that pointer value, it's just a random invalid address in the client's process space. Trying to dereference it (read/write to that address) will immediately trigger a segmentation fault. Even if you allocated memory for date on the client beforehand, the incoming struct will overwrite that pointer value with the server's local address, rendering your pre-allocated memory useless.
Fix Options to Try
1. Switch to a Fixed-Size Character Array (Simplest Solution)
If your time string has a predictable maximum length (e.g., RFC 3339 formatted time is ~30 characters), replace the pointer with a fixed-size array. This makes the entire struct a contiguous block of memory that can be safely sent and received as a whole:
// Updated response struct (client and server must use this same definition) struct timeStructResponse { int header[4]; int requestID; int length; // Can still keep this to track actual string length char date[64]; // Large enough to hold any reasonable time string + null terminator };
When the server fills date, it can use strncpy to avoid buffer overflow, and set length to strlen(date) for clarity. The client can directly read the string from the array without any pointer dereferencing risks.
2. Use Chunked Transmission (For Dynamic String Lengths)
If you need variable-length strings and can't use a fixed array, split the transmission into two parts:
- Step 1: Server sends a minimal struct containing
header,requestID, andlength(nodatepointer). - Step 2: Client receives this minimal struct, then allocates memory for
dateusing thelengthvalue:char* date = malloc(length + 1); // +1 for null terminator if (!date) { /* Handle allocation failure */ } - Step 3: Server sends the raw time string data (the actual characters, not a pointer).
- Step 4: Client receives the string into the pre-allocated
datebuffer.
3. Fix Memory Alignment (Secondary Check)
Even if you fix the pointer issue, mismatched memory alignment between client and server can cause field offsets to be wrong, leading to corrupted data (and potentially segfaults). Force consistent alignment with compiler attributes (works for GCC/Clang):
// Add __attribute__((packed)) to both structs in client and server code struct timeStructQuer __attribute__((packed)) { int header[4]; int requestID; }; struct timeStructResponse __attribute__((packed)) { int header[4]; int requestID; int length; char date[64]; // Or keep as pointer if using chunked transmission };
Debugging Steps to Confirm the Issue
- Use
gdbon your client: Set a breakpoint inreceiveTimeResponseand inspect thedatepointer value. If it's a random-looking number (not the address returned by yourmalloccall), that confirms the server's pointer is being sent and overwriting your local allocation. - Check the return value of
recvin your client code: Ensure you're receiving exactly the number of bytes you expect (e.g.,sizeof(struct timeStructResponse)for the fixed-array approach). Partial reads can corrupt struct fields.
内容的提问来源于stack exchange,提问作者Senio Vak

