【问题标题】:C++ - Run-Time Check Failure #2 - Stack around variable 'sourceCount' was corruptedC++ - 运行时检查失败 #2 - 变量“sourceCount”周围的堆栈已损坏
【发布时间】:2014-04-28 12:36:35
【问题描述】:

我发现了类似的 SO 问题,但与我的 here 不同。

我的函数如下所示:

BOOL ShallowCopy(const LPVOID psource, LPVOID pdest) {
    LPBYTE ps = reinterpret_cast<LPBYTE>(psource);
    LPBYTE pd = reinterpret_cast<LPBYTE>(pdest);
    ULONG sourceCount = 0, destCount = 0;

    std::copy(ps, ps + 8, checked_array_iterator<LPBYTE>(((LPBYTE)((LPVOID)&sourceCount)), 8)); // Get psource byte count
    std::copy(pd, pd + 8, checked_array_iterator<LPBYTE>(((LPBYTE)((LPVOID)&destCount)), 8));       //  Get pdest byte count

    if (sourceCount != destCount) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    std::copy(ps, ps + sourceCount, checked_array_iterator<unsigned char *>(pd, destCount));
    return TRUE;
}

当我这样调用函数时:

if (!ShallowCopy(pcsbi, &csbi)) {
    cerr << _T("FATAL: Shallow copy failed.") << endl;
}

系统抛出运行时异常,提示“运行时检查失败 #2 - 围绕变量 'sourceCount' 的堆栈已损坏。”

但是,如果我将 sourceCount 和 destCount 转换为变量,则不会出现此错误:

    BOOL ShallowCopy(const LPVOID psource, LPVOID pdest) {
    LPBYTE ps = reinterpret_cast<LPBYTE>(psource);
    LPBYTE pd = reinterpret_cast<LPBYTE>(pdest);
    LPBYTE pbCount = new BYTE[8];
    ULONG sourceCount = 0, destCount = 0;

    std::copy(ps, ps + 8, checked_array_iterator<LPBYTE>(pbCount, 8));  // Get psource byte count
    sourceCount = *((PULONG)pbCount);
    std::copy(pd, pd + 8, checked_array_iterator<LPBYTE>(pbCount, 8));      //  Get pdest byte count
    destCount = *((PULONG)pbCount);

    delete[] pbCount;

    if (sourceCount != destCount) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    std::copy(ps, ps + sourceCount, checked_array_iterator<unsigned char *>(pd, destCount));
    return TRUE;
}

当我查看这 2 个函数时,我看不出有什么区别,只是后来将值存储到变量中,然后转换为目标。那么,究竟是什么导致了运行时错误呢?

【问题讨论】:

  • csbipcsbi 是什么?

标签: c++


【解决方案1】:

ULONG 被定义为 unsigned long 那么它只是 32 位(4 个字节,而不是您的代码中的 8 个字节)。

你有这个错误是因为你在堆栈分配变量destCount(或sourceCount,它们的位置和顺序只是一个实现细节)之后覆盖了内存。在您的第二个示例中,它有效,因为您分配了足够的内存(pbCount 是 8 个字节),而这个 sourceCount = *((PULONG)pbCount); 将只复制其中的 4 个。

我建议使用sizeof 而不是硬编码的数据类型大小:

std::copy(ps, ps + sizeof(ULONG)...

请注意,您甚至可以简单地写:

sourceCount = *reinterpret_cast<PULONG>(ps);
destCount = *reinterpret_cast<PULONG>(pd);

【讨论】:

  • 非常感谢,你的解释正是我要找的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 2013-12-13
  • 2013-12-10
  • 2015-02-09
  • 2015-05-24
相关资源
最近更新 更多