求助:共享内存中调用memcpy触发段错误的原因排查
Alright, let's break down the probable reasons you're hitting a segmentation fault when using memcpy with your shared memory setup, and how to fix them:
1. Incorrect Shared Memory Size Calculation
First, your shm_size line is truncated (sizeof(osmp_msg[count][OSMP_MAX_MESSAG...), which means you're probably not calculating the total required memory correctly. Even if you intended to finish it, there are two common pitfalls here:
- Memory Alignment: C structs often have padding bytes added for alignment. Using
sizeof(shm_conf)gives you the correct size including padding, but if you're manually adding offsets later, you need to ensure you account for this (or useoffsetofto get precise positions of struct members). - Insufficient Allocation: If the calculated
shm_sizeis smaller than the actual memory you need forshm_conf+ the two additional arrays, any write (includingmemcpy) beyond the allocated range will trigger a segfault.
Fix this by completing the size calculation properly:
size_t shm_size = sizeof(shm_conf) + sizeof(int[count][2]) + sizeof(osmp_msg[count][OSMP_MAX_MESSAGES_PROC]);
2. Failed Shared Memory Mapping
If you didn't properly check the return values of shm_open or mmap, you might be working with an invalid memory pointer. For example:
shm_openreturns-1on failure, leaving you with an invalid file descriptor.mmapreturnsMAP_FAILED(a pointer to-1) if mapping fails. Using this invalid pointer inmemcpywill immediately cause a segfault.
Always validate these steps:
int shm_fd = shm_open(SHARED_MEMORY_NAME, O_CREAT | O_RDWR, 0666); if (shm_fd == -1) { perror("shm_open failed"); exit(EXIT_FAILURE); } if (ftruncate(shm_fd, shm_size) == -1) { perror("ftruncate failed"); close(shm_fd); shm_unlink(SHARED_MEMORY_NAME); exit(EXIT_FAILURE); } memory_conf = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (memory_conf == MAP_FAILED) { perror("mmap failed"); close(shm_fd); shm_unlink(SHARED_MEMORY_NAME); exit(EXIT_FAILURE); }
3. Out-of-Bounds Memory Access
Even if the shared memory is mapped correctly, you might be passing invalid pointers to memcpy. For example:
- If
countis larger than expected, the additional arrays (int[count][2]andosmp_msg[count][OSMP_MAX_MESSAGES_PROC]) could exceed the allocatedshm_size. - You might be calculating the offset to these arrays incorrectly (e.g., not accounting for struct padding), leading you to write outside the valid memory range.
To avoid this, calculate pointers to the additional arrays safely using byte offsets:
// Pointer to the int[count][2] array int (*int_array)[2] = (int (*)[2])((char*)memory_conf + sizeof(shm_conf)); // Pointer to the osmp_msg[count][OSMP_MAX_MESSAGES_PROC] array osmp_msg (*msg_array)[OSMP_MAX_MESSAGES_PROC] = (osmp_msg (*)[OSMP_MAX_MESSAGES_PROC])((char*)int_array + sizeof(int[count][2]));
This ensures you're always accessing memory within the bounds of your allocated shared memory.
内容的提问来源于stack exchange,提问作者Basti G.

