共享内存程序中i设为4时while循环出现段错误的原因求助
共享内存程序段错误排查与修复
核心问题:栈空间溢出
当i=4时,size = 8*16^4 = 524288(512KB),代码里父子进程都在栈上声明了char str[size];。而进程的栈空间默认容量有限(通常在几MB以内,不同系统有差异),这么大的数组直接分配在栈上会触发栈溢出,直接导致段错误。你看到的错误出现在while循环附近,只是栈溢出的触发点巧合落在这个位置,本质和循环逻辑无关。
其他潜在问题及修复
- 浮点数计算精度误差:
pow是浮点函数,计算整数幂时可能出现精度丢失,导致size值不准确。改用整数运算替代:// 替换pow的整数计算方式,避免浮点精度问题 int size = 8; for(int k=0; k<i; k++){ size *= 16; } - 信号量未初始化:
semget创建信号量后初始值是随机的,子进程的等待逻辑可能陷入死循环或异常。fork前要初始化信号量为0:int sem = semget(sem_key, 1, IPC_CREAT | 0666); semctl(sem, 0, SETVAL, 0); // 初始化信号量为0,父进程写完后再设为1 - 数组越界:父进程循环里
str[++j] = '\0';会访问str[size],超出数组边界(数组大小为size,索引范围是0~size-1)。正确写法:char *str = malloc(size); for(int j=0; j<size-1; j++){ str[j] = '1'; } str[size-1] = '\0'; - 栈溢出彻底解决:把栈上的大数组改成
malloc动态分配,堆空间的容量远大于栈,不会出现溢出问题。
修复后的完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/types.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/wait.h> int main() { int i = 4, pid, status, shmid; key_t key, sem_key; // 整数运算计算size,避免浮点精度丢失 int size = 8; for(int k=0; k<i; k++){ size *= 16; } key = ftok(".", 'x'); sem_key = ftok(".", 'y'); if ((shmid = shmget(key, size, IPC_CREAT | 0666)) == -1) exit(1); char *shmPtr = shmat(shmid, 0, 0); if(shmPtr == (char*)-1) exit(1); // 检查共享内存挂载是否成功 int sem = semget(sem_key, 1, IPC_CREAT | 0666); semctl(sem, 0, SETVAL, 0); // 初始化信号量为0 pid = fork(); if (pid == 0) { // 等待父进程写入完成 while(semctl(sem, 0, GETVAL) != 1); // 动态分配内存存储读取内容 char *str = malloc(size); if(!str) exit(1); strcpy(str, shmPtr); printf("子进程读取到的字符串长度:%zu\n", strlen(str)); free(str); exit(0); } else { // 动态分配内存存储要写入的内容 char *str = malloc(size); if(!str) exit(1); for (int j = 0; j < size-1; j++) { str[j] = '1'; } str[size-1] = '\0'; strcpy(shmPtr, str); semctl(sem, 0, SETVAL, 1); // 通知子进程可以读取 free(str); } wait(&status); shmdt(shmPtr); shmctl(shmid, IPC_RMID, NULL); semctl(sem, 0, IPC_RMID); return 0; }
内容的提问来源于stack exchange,提问作者bleedcloud
相关产品推荐
相关产品推荐

