2013-10-28 17 views
1

我需要強制執行一些SSE內存邊界來編寫代碼,但我在使用Visual Studio的內存檢查器時遇到了一些麻煩。我想知道爲什麼VS認爲有內存被損壞?爲什麼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; 
} 
+1

什麼是確切的錯誤信息?最後一行在哪兩個代碼塊? –

+0

你可以發佈錯誤消息嗎?將幫助我們幫助你:) – GMasucci

回答

1

當我試圖運行你的代碼,我發現了以下內容:

你的代碼中缺少右值賦值運算符。沒有它,它看起來的AcqBuffers內容被移動,當你調用ac = AlignedContainer(h * w, 4);

不知何故,類仍然hols的AcqBuffers內容(後被移動)刪除它時被毀。當ac的析構函數被調用時,析構函數再次刪除AcqBuffers,導致運行時錯誤。

要解決這個問題,你需要補充一點:

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

Raxvan。

+0

要評論我的問題,我看到你使用的是VS 2012,這不適用於標準的C++ 03,僅適用於C++ 11及更高版本。 @Joachim Pileborg解釋了複製過程中會發生什麼。有趣的是爲什麼編譯器不生成默認的深層複製操作符,因爲所有成員都有深度複製實現 – Raxvan

+0

不深_enough_。編譯器會調用'std :: vector '的副本,'std :: vector '會正確地複製一個'T'。但是'void *'的副本必然是一個淺拷貝。 – MSalters

2

聲明

ac = AlignedContainer(h * w, 4); 

首先創建一個臨時對象,被複制(用拷貝賦值運算符),以ac。但是,因爲您不提供複製賦值操作符,所以會調用默認的操作符,而這隻會執行淺拷貝。所以當臨時對象被銷燬時,臨時對象分配的內存被刪除,所以ac對象有指向未分配內存的指針,然後它嘗試刪除它自己。您需要了解the rule of three

相關問題