【unix系统编程】mmap创建映射区,提示mmap:invalid argument!

 mmap创建映射区,提示mmap:invalid argument!

我的原因是,

txt文件大小0,报错。
txt文件必须。必须要有实际大小。

#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>

  
int main()
{

    int fd = open("mmap_test.txt", O_RDWR);// 打开一个文件
    int len = lseek(fd, 0, SEEK_END);//获取文件大小
    // 创建内存映射区
    void *ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }
    close(fd); //关闭文件



    
    // 创建子进程
    pid_t pid = fork();
    if (pid == 0) //子进程
    {
        sleep(1); //演示,保证父进程先执行
        // 读数据
        printf("%s\n", (char*)ptr);
    }
    else if (pid > 0) //父进程
    {
        // 写数据
        strcpy((char*)ptr, "i am u father!!");
        // 回收子进程资源
        wait(NULL);
    }




    // 释放内存映射区
    int ret = munmap(ptr, len);
    if (ret == -1)
    {
        perror("munmap error");
        exit(1);
    }

}  

测试:

当txt文件为空时

 

 当填进去一个字符时:

 

 /

最后:mmap注意事项:

  • 注意事项
    • 1) 创建映射区的过程中,隐含着一次对映射文件的读操作。
    • 2) 当MAP_SHARED时,要求:映射区的权限应 <=文件打开的权限(出于对映射区的保护)。而MAP_PRIVATE则无所谓,因为mmap中的权限是对内存的限制。
    • 3) 映射区的释放与文件关闭无关。只要映射建立成功,文件可以立即关闭。
    • 4) 特别注意,当映射文件大小为0时,不能创建映射区。所以,用于映射的文件必须要有实际大小。mmap使用时常常会出现总线错误,通常是由于共享文件存储空间大小引起的。
    • 5) munmap传入的地址一定是mmap的返回地址。坚决杜绝指针++操作。
    • 6) 如果文件偏移量必须为4K的整数倍。
    • 7) mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功再进行后续操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如果你在运行上述代码时遇到 `mmap: Invalid argument` 的错误,可能是由于视频设备的分辨率不支持程序中设置的分辨率所导致的。 你可以尝试修改 `IMAGE_WIDTH` 和 `IMAGE_HEIGHT` 的值为你的摄像头支持的分辨率,或者使用以下代码查询摄像头支持的分辨率: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/ioctl.h> #include <linux/videodev2.h> #define DEVICE "/dev/video0" int main(int argc, char **argv) { int fd = 0; struct v4l2_capability cap; struct v4l2_fmtdesc format; struct v4l2_frmsizeenum framesize; int ret = 0; // 打开视频设备 fd = open(DEVICE, O_RDWR); if (-1 == fd) { perror("open"); return errno; } // 查询设备能力 ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); if (-1 == ret) { perror("ioctl(VIDIOC_QUERYCAP)"); return errno; } // 打印支持的格式 printf("Supported formats:\n"); memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while (0 == ioctl(fd, VIDIOC_ENUM_FMT, &format)) { printf("\t%s\n", format.description); format.index++; } // 打印支持的分辨率 printf("Supported framesizes:\n"); memset(&framesize, 0, sizeof(framesize)); framesize.pixel_format = V4L2_PIX_FMT_YUYV; while (0 == ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &framesize)) { if (framesize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { printf("\t%dx%d\n", framesize.discrete.width, framesize.discrete.height); } framesize.index++; } // 关闭设备 close(fd); return 0; } ``` 该代码能够打印出摄像头支持的格式和分辨率,你可以根据打印结果修改程序中的分辨率设置,或者手动调整摄像头的分辨率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pull_future

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值