2016-07-27 22 views
0

eine ID3D11Texture2D auf ein Byte-Array Kopieren verursacht außerhalb des Speicherfehler C++eine ID3D11Texture2D auf ein Byte-Array Kopieren, was außerhalb des Speicherfehler C++

Die Kopie für jeden Rahmen geschieht, und er läuft für etwa 5 Sekunden, bis I holen Sie sich die Speicherfehler, die auf entweder geschieht

HRESULT hr = device->CreateTexture2D(&description, NULL, &texTemp); 

Ergebnis in GetImageData Rückkehr NULL

OR

, wenn ein neuer Byte-Array wird bei

BYTE* dest = new BYTE[(*nWidth)*(*nHeight) * 4]; 

Giving erstellt,

Unbehandelte Ausnahme bei 0x76414DBD in NDIlib_Send_Video.x86.exe: Microsoft C++ Ausnahme: std :: bad_alloc an Speicherplatz 0x0107F5D8

Ich bin mir nicht sicher, welchen Speicher ich freigeben sollte, wahrscheinlich die Byte-Arrays .., Ich habe dies mit delete [] aByteArray versucht, aber dies verursacht einen Absturz.

Hier ist meine Funktion, um die Kopie zu tun,

BYTE* GetImageData(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, /*OUT*/ int* nWidth, /*OUT*/ int* nHeight) { 
    if (texture) { 
     D3D11_TEXTURE2D_DESC description; 
     texture->GetDesc(&description); 
     description.BindFlags = 0; 
     description.CPUAccessFlags = D3D11_CPU_ACCESS_READ |  D3D11_CPU_ACCESS_WRITE; 
     description.Usage = D3D11_USAGE_STAGING; 

     ID3D11Texture2D* texTemp = NULL; 

     HRESULT hr = device->CreateTexture2D(&description, NULL, &texTemp); 
     if (FAILED(hr)) 
     { 
      if (hr == E_OUTOFMEMORY) { 
       printf("GetImageData - CreateTexture2D - OUT OF MEMORY \n"); 
      } 
      if (texTemp) 
      { 
       texTemp->Release(); 
       texTemp = NULL; 
      } 
      return NULL; 
     } 
     context->CopyResource(texTemp, texture); 

     D3D11_MAPPED_SUBRESOURCE mapped; 
     unsigned int subresource = 0; 
     hr = context->Map(texTemp, 0, D3D11_MAP_READ, 0, &mapped); 
     if (FAILED(hr)) 
     { 
      printf("GetImageData - Map - FAILED \n"); 
      texTemp->Release(); 
      texTemp = NULL; 
      return NULL; 
     } 

     *nWidth = description.Width; 
     *nHeight = description.Height; 
     const int pitch = mapped.RowPitch; 
     BYTE* source = (BYTE*)(mapped.pData); 
     BYTE* dest = new BYTE[(*nWidth)*(*nHeight) * 4]; 
     BYTE* destTemp = dest; 
     for (int i = 0; i < *nHeight; ++i) 
     { 
      memcpy(destTemp, source, *nWidth * 4); 
      source += pitch; 
      destTemp += *nWidth * 4; 
     } 
     context->Unmap(texTemp, 0); 
     return dest;   
    } 
    else { 
     printf("GetImageData - texture null - FAILED \n"); 
     return NULL; 
    } 

} 

Und hier ist, wie ich GetImageData von meiner Hauptfunktion

 BYTE* p_frame = (BYTE*)GetImageData(g_d3dDevice, g_d3dDeviceContext, g_pDeskTexture, &w, &h); 

     if (p_frame == NULL) printf("GetImageData - Returned NULL \n"); 
     else { 
      printf("GetImageData - OK \n"); 
     } 
+0

Nach 'Unmap' geben Sie' context' nicht frei. Wenn Sie nicht sicher sind, was Sie mit Schnittstellen-Zeigern und ihrer Refcount-Verwaltung tun sollen, sollten Sie lieber Template-Wrapper-Klassen verwenden, die die Verwaltung für Sie übernehmen. –

+0

Danke, das hat mich in die richtige Richtung gewiesen. Ich musste meine Byte-Arrays löschen und auch die Textur freigeben. – Harvey3141

Antwort

1

bin mit Wo löschen Sie dest* oder in dem Fall nach zurückgegeben werden p_frame*? Sie ordnen Daten mit new zu und geben diesen Zeiger zurück, wenn Sie diesen nicht löschen, wird Ihnen schließlich der Speicher ausgehen, besonders wenn Sie diesen Frame aufrufen.

Sie sollten auch eine Form der Speicherverwaltung in Betracht ziehen und das Eigentumsrecht an dem, was zugewiesen wird, definieren. Das Zurückgeben von rohen Zeigern ist ein Hauptverdächtiger für Speicherlecks.

+0

'' std :: unique_ptr '' (siehe [Intelligente Zeiger (Modern C++)] (https://msdn.microsoft.com/en-us/library/hh279674.aspx)) und [Microsoft :: WRL :: ComPtr] (https://github.com/Microsoft/DirectXTK/wiki/ComPtr) ist dein Freund. –