写入映射数据时出现总线错误

Bus Error when writing to mmaped data

当我上学期第一次做这个项目时,代码运行良好。现在,在写入要在进程之间共享的映射内存时出现总线错误,我不确定为什么它不再工作了。

Account_Info *mapData()
{
    int fd;
    //open/create file with read and write permission and check return value
    if ((fd = open("accounts", O_RDWR|O_CREAT, 0644)) == -1)
    {
            perror("Unable to open account list file.");
            exit(0);
    }

    //map data to be shared with different processes
    Account_Info *accounts = mmap((void*)0, (size_t) 100*(sizeof(Account_Info)), PROT_WRITE,
    MAP_SHARED, fd, 0);

    int count= 0;

    //loop to initialize values of Account_Info struct
    while (count != 20)
    {
            //bus error occurs here
            accounts[count].CurrBalance= 0;
            accounts[count].flag = 0;
            int i = 0;
            while (i != 100)
            {
                    //place NULL terminator into each element of AccName
                    accounts[count].AccName[i]= '[=10=]';
                    i++;
            }

            count++;
    }

    close(fd);
    return accounts;
}

如果您尝试写入超过文件的映射区域,您将得到 SIGBUS

很可能您的后备存储文件 accounts 很短 truncated/too。 (例如)如果文件有 10 个结构条目的 space 而你写入第 11 个,你将得到 SIGBUS

执行 fstat 以获得 st_size 并将其与您提供给 mmap

的长度参数进行比较

您可能需要考虑在执行 mmap

之前使用 ftruncate 扩展文件

SIGBUS 与 mmap 的记录原因是

Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).

我猜 accounts 文件不存在,所以 openO_CREAT 创建了它。但它的大小为零,因此任何通过映射读取或写入的尝试都会出错。您需要用足够的零(或其他东西)填充文件以覆盖映射,例如使用 ftruncate.