1

我需要为我正在编写的代码强制执行一些 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;
}
4

2 回答 2

2

该声明

ac = AlignedContainer(h * w, 4);

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

您需要阅读有关三的规则

于 2013-10-28T11:10:28.283 回答
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);
}

拉克斯万。

于 2013-10-28T11:18:45.717 回答