You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言父子进程共享内存输出无间隔问题求助(Collatz猜想场景)

问题分析与修复

你的核心问题是子进程中计算共享内存指针偏移的逻辑完全错误:
你用char *a = (char *) &n; ptr += strlen(a);来计算偏移,这里&n是int变量的内存地址,strlen(a)会把int的二进制数据当作字符串读取,直到遇到字节0,这和数字转成字符串后的长度毫无关系,导致ptr的偏移量远小于实际写入的字符数,后续的sprintf会直接覆盖之前写入的空格,最终所有数字连在一起。

修复方案

正确的偏移计算方式

每次调用sprintf后,直接用它的返回值(返回写入的字符总数,不含终止符)来偏移ptr;或者用strlen(ptr)获取当前写入的字符串长度再偏移,两种方式都可以。

修正后的代码

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/mman.h>

int main(int argc, char** argv){
    const int SIZE = 4096; // Shared memory size
    const char* name = "COLLATZ"; // Shared Memory Name
    int n = atoi(argv[1]);
    pid_t pid = fork(); // process divergence

    int shm_fd; // shared memory file descriptor
    void *ptr; // shared memory pointer
    shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); // create shared memory object
    ftruncate(shm_fd, SIZE); // configure size of the shared memory
    ptr = mmap(0, SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, shm_fd, 0); // 父进程需要读权限,添加PROT_READ
    close(shm_fd); // 映射完成后可关闭文件描述符,不影响共享内存使用

    if(pid == 0){
        // 子进程:生成Collatz序列写入共享内存
        char *current_ptr = ptr; // 用临时指针记录当前写入位置,逻辑更清晰
        while(n > 1){
            // 用sprintf返回值获取写入字符数,直接偏移指针
            int written = sprintf(current_ptr, "%d ", n);
            current_ptr += written;

            // Collatz序列逻辑
            if(n % 2 == 0){
                n = n / 2;
            } else {
                n = 3 * n + 1;
            }
        }
        // 写入最后一个数字,末尾不加空格
        sprintf(current_ptr, "%d", n);
    } else if(pid > 0){
        wait(NULL);
        printf("%s\n", (char *)ptr); // 读取共享内存起始位置的内容
    }
    shm_unlink(name); // 删除共享内存对象
    return 0;
}

额外优化点

  1. 父进程映射共享内存时添加PROT_READ权限,权限配置更合理。
  2. 映射完成后关闭shm_fd,避免资源泄漏。
  3. 最后一个数字后不再写入空格,避免输出末尾多余空格。
  4. 用临时指针current_ptr记录写入位置,避免修改原ptr,代码逻辑更清晰。

测试结果

运行程序输入./your_program 8,会正确输出:8 4 2 1

内容的提问来源于stack exchange,提问作者Cmcbride

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:02:09