0

I have this program where i need to allocate memory to obtain some information of a driver. C++14.

The process is to call a function that returns a pointer to where the information is stored, and then i need to allocate an array (of a custom struct) and assign the pointer/memory to my array to access the information.

I have the program working with new/delete but i wanted to implement smart pointers to avoid possible memory leaks. This is my working code:

// Custom struct to obtain the pointer
typedef struct tag_SelectData
{                               // Selectable data information data structure.
    short iCount;               // The number of selectable data
    short iSize;                // The number of byte per one data selected.
    int *lpData;                // Pointer to the arrays of selectable data.
                                // *The application must allocate the buffer for this member and set
                                // the parameter the address of the buffer.
                                // If the lpData parameter is 0, the function outputs only iCount and iSize.
} SELECTDATA;

// The struct where i obtain the information
typedef struct tag_MediaTypeRange_4
{
    DWORD dwVersion;     // This structure version. must be 4.
    DWORD dwSize;            // This structure size.
    long iMaxWid;     // Maximum width.
    long iMaxHig;     // Maximum height.
    long iMinWid;     // Minimum width.
    long iMinHig;     // Minimum height.
    long iTypeID;            // Media type ID
} MEDIATYPERANGE_4;

/***  My program  ***/
SELECTDATA selectData;  //Define struct
selectData.iCount = 0;
selectData.iSize = 0;
selectData.lpData = NULL

GetSelectDataRange(CMD_MEDIATYPE, &selectData);  //Get pointer of memory

MEDIATYPERANGE_4 *arr = new MEDIATYPERANGE_4[selectData.iCount]; //Allocate array memory
arr = (MEDIATYPERANGE_4 *)selectData.lpData;  // Assign pointer to allocated pointer

for (size_t i = 0; i < selectData.iCount; i++)  // Iterate array and show results
{
  std::cout << arr[i].iMaxWid << std::endl;
  std::cout << arr[i].iMinWid << std::endl;
  std::cout << arr[i].iMaxHig << std::endl;
  std::cout << arr[i].iMinHig << std::endl;
}  //Works ok

Im having trouble in the "assign" part of the smart pointer.

//Create a smart pointer of custom struct
std::shared_ptr<MEDIALAYOUTRANGE_4[]> mediaArr(new MEDIALAYOUTRANGE_4[selectData.iCount]());

How do i assign the memory to my smart pointer? I know that later i can access with mediaArr.get[i] but with the smart pointer creation i only allocate memory, but im missing the part of the pointer assignment. I can't CStyle Cast because it wont compile.

std::shared_ptr<MEDIALAYOUTRANGE_4 []> mediaArr = (MEDIATYPERANGE_4 *)selectData.lpData; //no suitable constructor

mediaArr = (MEDIATYPERANGE_4 *)selectData.lpData; //no operator = matches the operands

Thanks.

rockstiff
  • 355
  • 1
  • 2
  • 17
  • See https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast – Alan Birtles Jun 24 '22 at 13:53
  • 2
    After reading the comments more carefully, it looks like you're supposed to point `selectData.lpData` at your buffer, rather than the opposite. So you'd create a `std::vector` of suitable size, and call the function with a `SELECTDATA` containing `{ vec.size(), sizeof vec[0], reinterpret_cast(vec.data()) }`. That's an odd API for sure. – Quentin Jun 24 '22 at 14:00
  • Indeed, just skip the ordinary smart pointer, and go for the ultra-smart pointer. It's called `std::vector`. – Sam Varshavchik Jun 24 '22 at 14:01
  • @AlanBirtles: OP misdiagnosed his issue, so your duplicate which addressed his title had no relation to the actual question. – Ben Voigt Jun 24 '22 at 16:19
  • 1
    Your "working" code is wrong, it has a memory leak and never does anything at all with the allocated memory. Perhaps the function `GetSelectDataRange` did an allocation on your behalf. The appropriate smart pointer here would be `std::unique_ptr` with a custom deleter associated with whatever cleanup function matches `GetSelectDataRange` (it won't be `operator delete[]`) – Ben Voigt Jun 24 '22 at 16:23
  • 1
    According to the comments on `struct tag_SelectData` however, your "working" program can't possibly be working. If `iCount` comes back from the function greater than zero, you would dereference a null pointer. – Ben Voigt Jun 24 '22 at 16:25
  • The comments do not provide sufficient information to show you how to correctly use it (whether with `new`, smart pointer or whatever). It says that `lpData` must point to caller-allocated memory, but it doesn't say how bounds of the memory are handled. You need to read the documentation for `GetSelectDataRange` carefully to determine how exactly it expects you to use it. – user17732522 Jun 24 '22 at 16:39

0 Answers0