为什么VS蛤蜊会侵犯记忆?

时间:2013-10-28 11:00:22

标签: c++ visual-studio-2012

我需要为我正在编写的代码强制执行一些SSE内存边界,但我在使用Visual Studio的内存检查程序时遇到了一些问题。我想知道为什么VS认为存在内存损坏?

#define sse_t float* __restrict
#include <iostream>
#include <assert.h>
#include <stdio.h>
using namespace std;
class AlignedContainer {
public:
    AlignedContainer(int n = 0, int frames = 0, size_t align = 16) {

        assert((align & (align - 1)) == 0);
        int bufferSize = sizeof(float) * n;
        for (int i = 0; i < frames; i++) {
            int alignedSize = bufferSize + 15;
            auto aqbuf = new unsigned char[alignedSize];
            auto aligned = reinterpret_cast < unsigned char *>((reinterpret_cast < size_t > (aqbuf) + 15) & ~15); // 16 bit alignment in preperation for SSE
            memset(aqbuf, 0, alignedSize); // for debugging, forces memory to instantly allocate
            AcqBuffers.push_back(aqbuf);
            displayFrames.push_back(aligned);
        }
    }

    ~AlignedContainer() {
            for (int i = 0; i < AcqBuffers.size(); i++) {
                delete[]AcqBuffers[i];
            }
            AcqBuffers.empty();
            displayFrames.empty();
        }

inline sse_t operator [] (int i) const {
        return (sse_t) displayFrames[i];
    }

private:
        vector < void *>displayFrames;
        vector < void *>AcqBuffers;
};

int main(int argc, char *argv[])
{
    int h = 2160;
    int w = 2544;
    AlignedContainer ac;
    ac = AlignedContainer(h * w, 4);
}

最后一行出错。

/***
*static int CheckBytes() - verify byte range set to proper value
*
*Purpose:
*       verify byte range set to proper value
*
*Entry:
*       unsigned char *pb       - pointer to start of byte range
*       unsigned char bCheck    - value byte range should be set to
*       size_t nSize            - size of byte range to be checked
*
*Return:
*       TRUE - if all bytes in range equal bcheck
*       FALSE otherwise
*
*******************************************************************************/
extern "C" static int __cdecl CheckBytes(
        unsigned char * pb,
        unsigned char bCheck,
        size_t nSize
        )
{
        while (nSize--)
        {
            if (*pb++ != bCheck)
            {
                return FALSE;
            }
        }
        return TRUE;
}

2 个答案:

答案 0 :(得分:2)

声明

ac = AlignedContainer(h * w, 4);

首先创建一个临时对象,将其复制(使用复制赋值运算符)到ac。但是因为您没有提供复制赋值运算符,所以会调用默认值,而这只会进行浅层复制。因此,当临时对象被销毁时,临时对象分配的内存将被删除,因此ac对象具有指向未分配内存的指针,然后它会尝试自行删除。

您需要阅读the rule of three

答案 1 :(得分:1)

当我尝试运行您的代码时,我发现了以下内容:

您的代码缺少右值赋值运算符。没有它,当您致电AcqBuffers

时,ac = AlignedContainer(h * w, 4);的内容似乎会被移动

不知何故,该类仍然保留AcqBuffers(被移动后)的内容,在销毁时将其删除。当ac的析构函数被调用时,析构函数再次删除AcqBuffers,导致运行时错误。

要解决此问题,您需要添加以下内容:

AlignedContainer& operator = (AlignedContainer && rv)
{
    displayFrames = std::move(rv.displayFrames);
    AcqBuffers = std::move(rv.AcqBuffers);
    return (*this);
}

Raxvan。