【问题标题】:Write access violation when trying to modify array尝试修改数组时写访问冲突
【发布时间】:2017-04-05 18:55:03
【问题描述】:

来自资源的文件被传递给函数 Change ,该函数应该对每个字节值进行异或,但随后出现写访问冲突错误。

INT CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
    HRSRC hRes = FindResource(NULL, L"FILE", RT_RCDATA);

    if (hRes == NULL)
    {
        // print error
    }

    DWORD resSize = SizeofResource(NULL, hRes);
    HGLOBAL resData = LoadResource(NULL, hRes);
    byte *file = reinterpret_cast<byte*>(LockResource(resData));

    Change(file, resSize);

    return 0;
}

void Change(byte *data, int size)
{
    for (int i = 0; i < size; ++i)
    {
        data[i] ^= 2;
    }
}

【问题讨论】:

  • 您检查LockResource 的返回值以确保它不为空吗?
  • 在内存窗口中,我可以看到文件变量包含我文件中的字节。
  • 资源位于可执行文件的只读段中。您不能修改资源占用的内存。

标签: c++ winapi visual-c++


【解决方案1】:

资源存在于只读内存中,不能直接写入。

修改资源内容的唯一方法是使用UpdateResource()(除非您将WriteFile()直接用于磁盘上的可执行文件),但您不能在属于正在运行的进程,因为可执行文件被操作系统锁定。

所以,做你正在尝试的唯一方法是在可写内存中分配资源数据的单独副本,然后你可以对该副本做任何你想做的事情,例如:

INT CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
    HRSRC hRes = FindResource(NULL, L"FILE", RT_RCDATA);
    if (hRes == NULL)
    {
        // print error
    }
    else
    {
        DWORD resSize = SizeofResource(NULL, hRes);
        HGLOBAL resData = LoadResource(NULL, hRes);
        LPVOID resDataPtr = LockResource(resData);

        byte *copy = new byte[resSize];
        memcpy(copy, resDataPtr, resSize);
        Change(copy, resSize);
        delete[] copy;
    }

    return 0;
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2023-03-27
相关资源
最近更新 更多