boost scoped_ptr/shared_ptr holding memory block of different size than size of object pointed to

StackOverflow https://stackoverflow.com/questions/23455720

  •  15-07-2023
  •  | 
  •  

Question

Actually when writting this question, another question a shorter one came to my mind so i will ask it first:

1st Question (Shorter):

I have a header with struct defined in this manner:

typedef struct _CAMERA_LIST
{
....
}CAMERA_LIST, *PCAMERA_LIST;

What is the meaning of this syntax? (note the difference in the struct name and the names after closing brace)

2nd Question (Longer):

I have a code example from hardware manufacturer showing how to properly initialize the hardware that Im using. In the code manufacturer uses raw pointers and in my application i would prefer to use boost scoped_ptr or shared_ptr. The problem is that memory block that i want to allocate is different size than that allocated by regular new ObjectType;

Here is the short version of what i got from the manufacturer's site:

int nNumCam = 3;
CAMERA_LIST* pucl;
pucl = (CAMERA_LIST*) new BYTE [sizeof (DWORD) + nNumCam * sizeof (CAMERA_INFO)];
pucl->dwCount = nNumCam;
printf("Camera %i Id: %d", iCamera, pucl->uci[1].dwCameraID);

And here is what i want to get:

int nNumCam = 3;
scoped_ptr<CAMERA_LIST> pucl;
pucl.reset( (CAMERA_LIST*) new BYTE [sizeof (DWORD) + nNumCam * sizeof (CAMERA_INFO)] );
pucl->dwCount = nNumCam;
printf("Camera %i Id: %d", iCamera, pucl->uci[1].dwCameraID);

Here is how the struct looks like exactly:

typedef struct _CAMERA_LIST
{
DWORD dwCount;
CAMERA_INFO uci[1];
}CAMERA_LIST, *PCAMERA_LIST;

The question is: How do I get this functionality to work with scoped_ptr/shared_ptr? Also note that in the code snippet the deletion of the memory block is done via delete[] not delete. Do i need to use scoped_array? If so how do access struct fields?

there is a complete example from manufacturers site in case anyone finds it helpful:

INT nNumCam;
if( is_GetNumberOfCameras( &nNumCam ) == IS_SUCCESS) {
if( nNumCam >= 1 ) {
  // Create new list with suitable size
  CAMERA_LIST* pucl;
  pucl = (CAMERA_LIST*) new BYTE [sizeof (DWORD) + nNumCam * sizeof (CAMERA_INFO)];
  pucl->dwCount = nNumCam;

  //Retrieve camera info
  if (is_GetCameraList(pucl) == IS_SUCCESS) {
    int iCamera;
    for (iCamera = 0; iCamera < (int)pucl->dwCount; iCamera++) {
      //Test output of camera info on the screen
      printf("Camera %i Id: %d", iCamera,
      pucl->uci[iCamera].dwCameraID);
    }
  }
}
delete [] pucl;
}
Was it helpful?

Solution

This is a job for a custom deleter.

struct delete_bytearr {
    void operator() ( void * ptr ) const
        { delete [] (BYTE *) ptr; }
};

boost::shared_ptr (and std::shared_ptr) accept a deleter object as a second constructor argument, but scoped_ptr does not. Its descendent std::unique_ptr does accept a custom deleter, and you should probably prefer the standard facilities moving forward.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top