如何解决Linux下C程序运行时的Segment fault (core dumped)问题?
解决共享内存程序的Segment Fault问题
问题根源
你的程序触发段错误的核心原因是缺失错误检查,以及共享内存对象不存在时的处理逻辑漏洞:
- 当调用
shm_open("hello_class", O_RDONLY, 0666)时,如果名为hello_class的共享内存对象不存在,该函数会返回-1(调用失败),但你直接使用这个无效的文件描述符执行mmap,导致mmap返回MAP_FAILED(无效内存地址),后续printf("%s", (char*)ptr)访问无效地址直接触发段错误。 void main()不符合C语言标准,标准定义应为int main(),部分编译器虽兼容,但属于不良编码习惯。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/types.h> #include <unistd.h> int main() { int shm_fd; void *ptr = NULL; // 打开共享内存,失败则输出错误并退出 shm_fd = shm_open("hello_class", O_RDONLY, 0666); if (shm_fd == -1) { perror("shm_open failed"); exit(EXIT_FAILURE); } // 获取共享内存实际大小,避免硬编码导致的内存问题 struct stat shm_stat; if (fstat(shm_fd, &shm_stat) == -1) { perror("fstat failed"); close(shm_fd); exit(EXIT_FAILURE); } // 映射共享内存,失败则输出错误并退出 ptr = mmap(0, shm_stat.st_size, PROT_READ, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { perror("mmap failed"); close(shm_fd); exit(EXIT_FAILURE); } // 打印共享内存中的字符串 printf("%s\n", (char*)ptr); // 按顺序释放资源:先解除映射,再关闭文件描述符,最后删除共享内存 munmap(ptr, shm_stat.st_size); close(shm_fd); shm_unlink("hello_class"); return 0; }
关键修复点
- 为
shm_open、fstat、mmap添加错误检查,用perror输出具体错误信息,便于调试定位问题。 - 用
fstat获取共享内存的实际大小,替代硬编码的4096,避免内存越界或资源浪费。 - 遵循资源释放顺序:先解除内存映射,再关闭文件描述符,最后删除共享内存对象,避免资源泄漏。
- 修正
main函数为标准的int main(),并返回0表示程序正常退出。
额外说明
如果该程序单独运行,需确保已有其他进程创建并写入hello_class共享内存对象,否则shm_open会直接失败。若要让程序自行创建共享内存,需在shm_open的flags参数中加入O_CREAT,示例:
shm_fd = shm_open("hello_class", O_RDONLY | O_CREAT, 0666);
但这种场景下还需先向共享内存写入数据,否则打印的是未初始化的内存内容,可能出现乱码或触发其他错误。
内容的提问来源于stack exchange,提问作者Uyên Phương
相关产品推荐
相关产品推荐

