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