1

I have trouble working with an unique_ptr. I am trying to work with the winapi and I succeeded to get the pixels from a bitmap with CreateDIBSection().

To have the pixels we have to create a BYTE* value and pass it to the function like so:

BYTE* bitPointer;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL); 

bitPointer has now 1080 * 1920 * (4 bytes per pixel) = 8,294,400 values in it.

To convert it in a unique_ptr I do:

std::unique_ptr<BYTE> bitSmartPtr(bitPointer);

But when I try to access to the value:

std::cout << bitSmartPtr.get()[0] << '\n'; 

I have the error "segmentation fault".

I tried to use the

std::unique_ptr<BYTE[]> bitSmartPtr(bitPointer) 

but I can't access to it with bitSmartPtr[0] I get the same error.

Do you know what I'm doing wrong and how can I convert it? I add that I don't think I can use another variable than a raw pointer to use in the CreateDIBSection() function.

Of course I can access easily to all values from the first pointer with a for loop

PsyKozZ09
  • 21
  • 3
  • 4
    Your usage of `std::unique_ptr` shouldn't be causing any segmentation faults, except in its destructor as the pointed to memory may not have been created using `new[]`. There also doesn't seem to be any good reason to use a smart pointer here, as there is nothing to `delete` or `delete[]` (as the memory is handled by an external system) – UnholySheep Jun 22 '23 at 09:45
  • The code doesn't seem to verify that `CreateDIBSection` worked. If it failed, and returned a NULL, *any* pointer use would also fail. – BoP Jun 22 '23 at 09:47
  • What is C++ standard you can use? – Marek R Jun 22 '23 at 09:56
  • I have to return the pointer to the main function (all this code is in a function) so I thought unique_ptr was the best to do that in safety. And to answer to BoP, I should check it yes but I can access to the value of the raw pointer so I think it succeed – PsyKozZ09 Jun 22 '23 at 10:02
  • 3
    Have you read the documentation on [CreateDibSection](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createdibsection). The memory allocated by it will be released when you close the HBITMAP, so you do NOT need to free yourself. If something has to be made into a RAII object it is an object that should manage HBITMAP – Pepijn Kramer Jun 22 '23 at 10:11
  • @PepijnKramer so when I do "DeleteObject(hbitmap)" the values of my first pointer is deleted too? And I read the documentation, but it's true that I don't understand everything in it. – PsyKozZ09 Jun 22 '23 at 10:14
  • @PepijnKramer Thank you for your answer. You were right, I was affecting my pointer to my unique_ptr before "DeleteObject(hbitmap)" and called the bitSmartPtr.get()[0] after. But if I do it before it works! – PsyKozZ09 Jun 22 '23 at 10:21
  • "the values of my first pointer is deleted too': no you do not delete the value of a pointer. In general you may deallocate the memory it pointed to (if it's the address of something properly allocated). In this situation, I think that you only get an dangling pointer (the pointer can still store the same value, which is an address where there can be anything now). – Oersted Jun 22 '23 at 10:49
  • 1
    Here is an example of using unique_ptr to utilize a provided handle_deleter: https://stackoverflow.com/a/27442473/4641116 – Eljay Jun 22 '23 at 11:55

1 Answers1

0

Creating a std::unique_ptr means you take ownership of the memory but here you cannot.
CreateDIBSection doc explains how memory is managed. Your only legal option is to use DeleteObject(), which you must not forget to do on the handle returned by CreateDIBSection.
But please read carefully the doc (and comments below).

Oersted
  • 769
  • 16
  • @nick I agree, fixed. – Oersted Jun 22 '23 at 10:10
  • Ok I see. So applying NULL to the hSection parameter doesn't allow me to give ownership to another variable? – PsyKozZ09 Jun 22 '23 at 10:10
  • It has nothing todo with a nullptr value here, the memory isn't managed by the calling code directly, it should be freed by calling DeleteObject on the HBITMAP. Which in turn will free the allocated memory – Pepijn Kramer Jun 22 '23 at 10:12
  • "If hSection is NULL, the system allocates memory for the DIB. In this case, the CreateDIBSection function ignores the dwOffset parameter. An application cannot later obtain a handle to this memory." the last sentence is what Oersted talked about? – PsyKozZ09 Jun 22 '23 at 10:16
  • 1
    I'm sorry I think I added confusion with this `ǸULL` story. As @PepijnKramer says, the calling code does not own the memory so it cannot transfer it (except if documented otherwise and if the called function is designed to allow this ownership transfer, which is not the case here). – Oersted Jun 22 '23 at 10:37
  • 1
    To be more complete. If you don't use `NULL`, you have to pass `A handle to a file-mapping object that the function will use to create the DIB`. You can then manage your memory with this object. See [CreateFileMapping](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga); but you'll get a handle, not a pointer, thus you will not be able to use `std::unique_ptr` either. It's then a all new story... – Oersted Jun 22 '23 at 10:40
  • Thank you for all these explanations @Oersted! – PsyKozZ09 Jun 22 '23 at 11:16
  • @Aconcagua Indeed, it could be compliant with the documentation. Yet the DeleteObject function applies to the handle, not the pointer. You cannot simply take the address of the returned handle which is included in some scope. – Oersted Jun 22 '23 at 15:48
  • @Oersted No, in given case it seems wrong – well, or *not*, but the custom deleter would't do anything at all, as Pepijn already denoted at the question… – Aconcagua Jun 22 '23 at 16:08