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

运行《Windows编程》PoePoem程序时触发资源内存访问违规求解决方案

解决Petzold《Windows编程》PoePoem程序内存访问违规问题

问题根源

  1. 只读内存限制:LockResource返回的指针指向Windows资源加载后的只读内存区域(内存映射文件的一部分),直接修改该内存会触发内存访问违规——这是Windows资源机制的固有规则,并非20年间的变化,只是旧版系统可能未严格强制执行。
  2. 字符编码不匹配:Visual Studio 2015默认采用Unicode字符集编译,而原书代码基于ANSI字符集,char*强制转换和AnsiNext函数在Unicode环境下会导致字符处理逻辑异常,甚至循环无法正确终止。

修复方案

步骤1:将资源内容复制到可写内存

必须先把只读的资源数据复制到可分配的内存块中,再进行修改操作。以下是适配ANSI字符集的代码示例:

HRSRC hResInfo;
HGLOBAL hResource;
DWORD dwResSize;
char* pText;
int iNumLines = 0;

// 获取资源信息并加载
hResInfo = FindResource(hInst, TEXT("AnnabelLee"), TEXT("TEXT"));
dwResSize = SizeofResource(hInst, hResInfo);
hResource = LoadResource(hInst, hResInfo);
const char* pReadOnlyText = (const char*)LockResource(hResource);

// 分配可写内存(+1是为了容纳结束符)
pText = (char*)LocalAlloc(LPTR, dwResSize + 1);
if (pText == NULL)
{
    // 处理内存分配失败
    return 0;
}

// 复制资源内容到可写内存
memcpy(pText, pReadOnlyText, dwResSize);

// 统计行数并修改结束符
char* p = pText;
// 注意:原代码中的循环条件应为单引号'\'',修正转义错误
while (*p != '\'' && *p != '\0')
{
    if (*p == '\n')
        iNumLines++;
    p = AnsiNext(p);
}
*p = '\0';

// 后续使用pText处理诗歌内容...

// 使用完毕后释放内存
LocalFree(pText);

步骤2:适配Unicode字符集(VS2015默认)

如果你的项目启用了Unicode字符集(项目属性 -> 配置属性 -> 常规 -> 字符集 -> 使用Unicode字符集),需改用宽字符类型处理,避免编码错误:

HRSRC hResInfo;
HGLOBAL hResource;
DWORD dwResSize;
wchar_t* pText;
int iNumLines = 0;

hResInfo = FindResource(hInst, L"AnnabelLee", L"TEXT");
dwResSize = SizeofResource(hInst, hResInfo);
hResource = LoadResource(hInst, hResInfo);
const wchar_t* pReadOnlyText = (const wchar_t*)LockResource(hResource);

// 分配宽字符可写内存
pText = (wchar_t*)LocalAlloc(LPTR, dwResSize + sizeof(wchar_t));
if (pText == NULL)
{
    return 0;
}

memcpy(pText, pReadOnlyText, dwResSize);

wchar_t* p = pText;
while (*p != L'\'' && *p != L'\0')
{
    if (*p == L'\n')
        iNumLines++;
    p = Next(p); // 宽字符使用Next函数,或直接p++(固定长度字符)
}
*p = L'\0';

// 后续处理...

LocalFree(pText);

额外注意事项

  • 确认resource.h和.rc文件中资源定义正确,例如.rc中应包含:
    AnnabelLee TEXT "AnnabelLee.txt"
  • 若原资源用反斜杠作为结束标记,需将循环条件中的'\''替换为'\\',确保逻辑匹配资源内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:36:06