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

Windows64下Qt+C++使用CreateFileMapping创建大共享内存失败求助

问题描述

需要通过共享内存在两个进程间传输10M及以上的大图片,但调用CreateFileMappingW时,当BUF_SIZE超过4096字节程序崩溃,后续发现问题出在MapViewOfFile调用上——当该函数最后一个参数设为4097及以上时,程序会卡住。开发环境为Windows 64位系统,使用Qt框架的C++开发。

相关代码如下:

hMapFile = CreateFileMappingW(
             INVALID_HANDLE_VALUE,    // use paging file
             NULL,                    // default security
             PAGE_READWRITE,          // read/write access
             0,                       // maximum object size (high-order DWORD)
             BUF_SIZE,                // maximum object size (low-order DWORD)超过4096就不行了,不知道怎么解决
             szMapName);
hMapFile = CreateFileMappingW(
         INVALID_HANDLE_VALUE,    // use paging file
         NULL,                    // default security
         PAGE_READWRITE,          // read/write access
         0,                       // maximum object size (high-order DWORD)
         BUF_SIZE,                // maximum object size (low-order DWORD)
         szMapName);                 // name of mapping object

if (hMapFile == NULL){
    qDebug() << (TEXT("Could not create file mapping object (%d)."),GetLastError());
    return -1;
}
pBuf = (LPTSTR)MapViewOfFile(
       hMapFile,   // handle to map object
       FILE_MAP_ALL_ACCESS, // read/write permission
       0,
       0,
       4097);//if this number > 4096, the program will stuck

if (pBuf == NULL){
    qDebug() << (TEXT("Could not map view of file (%d)."),
    GetLastError());
    CloseHandle(hMapFile);
    return -1;
}

解决方法

1. 正确设置MapViewOfFile的映射大小

MapViewOfFile的最后一个参数指定为0,表示映射整个文件映射对象的全部大小,这是处理大内存映射的标准做法,既能避免手动指定大小带来的页对齐问题,也能适配任意大小的共享内存(包括10M以上的图片)。修改后的调用代码:

pBuf = (BYTE*)MapViewOfFile(
       hMapFile,
       FILE_MAP_ALL_ACCESS,
       0,
       0,
       0); // 映射整个共享内存区域

另外,因为传输的是图片二进制数据,将指针类型转为BYTE*比LPTSTR更合适,避免字符编码相关的潜在问题。

2. 修正错误输出逻辑

原代码中的qDebug()使用了逗号表达式,只会输出GetLastError()的值,错误信息字符串无法正常打印,这会导致排查问题时无法准确判断错误原因。修改为正确的输出方式:

if (hMapFile == NULL){
    qDebug() << TEXT("Could not create file mapping object (%d).") << GetLastError();
    return -1;
}
if (pBuf == NULL){
    qDebug() << TEXT("Could not map view of file (%d).") << GetLastError();
    CloseHandle(hMapFile);
    return -1;
}

3. 确保BUF_SIZE的正确性

对于10M大小的内存,BUF_SIZE应设置为10 * 1024 * 1024(即10485760),这个值在32位DWORD的范围内(最大为4294967295),因此CreateFileMappingW的高32位参数设为0是正确的。如果后续需要传输更大的文件(超过4GB),则需要将文件大小拆分为高32位和低32位传入。

4. 规避内存页对齐问题

Windows的内存映射是以4KB(4096字节)为一页进行对齐的,手动指定映射大小如果不是页的整数倍,系统会自动向上取整到最近的页边界,但这种操作可能引发意外的内存访问问题。使用0映射整个区域可以完全规避这个问题。

5. 增加进程间同步(可选但关键)

如果两个进程需要读写共享内存,建议配合使用互斥量(CreateMutexW)或事件(CreateEventW)进行同步,避免出现读写冲突导致的程序卡住或数据损坏问题。例如在写入进程写完数据后触发事件,通知读取进程可以开始读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:55:17