1

I have this structure:

using SPECIAL_EVENT_S = struct tagSpecialEvent 
{
    COleDateTime    datEvent;
    CString         strEvent;
    CString         strLocation;
    int             iSRREventType;
    int             iSMREventType;
    int             iForeignLanguageGroupMenuID;

    COleDateTime    datEventStartTime;
    COleDateTime    datEventFinishTime;
    BOOL            bEventAllDay;

    BOOL            bSetReminder;
    int             iReminderUnitType;
    int             iReminderInterval;

    int             iImageWidthPercent;
    CString         strImagePath;
    CString         strTextBeforeImage;
    CString         strTextAfterImage;
    CChristianLifeMinistryDefines::VideoConferenceEventType eType;
};

And I have instances of this structure as pointers in CListBox items. I now have a need to duplicate a structure so that it is a new instance. At the moment I am doing it like this:

auto* psThisEvent = static_cast<SPECIAL_EVENT_S*>(m_lbEvents.GetItemDataPtr(iThisEventIndex));
if (psThisEvent == nullptr)
    return;

auto* psNewEvent = new SPECIAL_EVENT_S;
if (psNewEvent == nullptr)
    return;

psNewEvent->bEventAllDay = psThisEvent->bEventAllDay;
psNewEvent->bSetReminder = psThisEvent->bSetReminder;
psNewEvent->datEvent = datNewEvent;
psNewEvent->datEventFinishTime = psThisEvent->datEventFinishTime;
psNewEvent->datEventStartTime = psThisEvent->datEventStartTime;
psNewEvent->eType = psThisEvent->eType;
psNewEvent->iForeignLanguageGroupMenuID = psThisEvent->iForeignLanguageGroupMenuID;
psNewEvent->iImageWidthPercent = psThisEvent->iImageWidthPercent;
psNewEvent->iReminderInterval = psThisEvent->iReminderInterval;
psNewEvent->iReminderUnitType = psThisEvent->iReminderUnitType;
psNewEvent->iSMREventType = psThisEvent->iSMREventType;
psNewEvent->iSRREventType = psThisEvent->iSRREventType;
psNewEvent->strEvent = psThisEvent->strEvent;
psNewEvent->strImagePath = psThisEvent->strImagePath;
psNewEvent->strLocation = psThisEvent->strLocation;
psNewEvent->strTextAfterImage = psThisEvent->strTextAfterImage;
psNewEvent->strTextBeforeImage = psThisEvent->strTextBeforeImage;

Is this the right way to go about this? I saw this question but I am not sure if it is safe to use memcpy in this case.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164

1 Answers1

2

I am not sure if it is safe to use memcpy in this case.

Your doubts are well-founded. The SPECIAL_EVENT_S structure has members that are not trivially copyable (i.e. cannot be properly copied using memcpy). For example, it contains several CString members – a class with embedded data buffers and pointers; thus if the structure is simply copied memory-to-memory, then destroying one structure (the destination) will potentially cause those data buffers of the CString objects in the other structure (the source) to be invalidated. You must call the CString copy constructor for each of those objects. (The same may also be true of the COleDateTime member objects.)

As mentioned in the comments, calling the implicitly-defined copy constructor or copy assignment operator for the SPECIAL_EVENT_S should take care of this; something along the lines of:

*psNewEvent = *psThisEvent;

But, as you have correctly noted, you will then need to explicitly assign the datEvent member after that copy constructor/assignment:

psNewEvent->datEvent = datNewEvent;
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83