See this code:
if (pAryStrCustom != nullptr)
{
const gsl::span spanAryStrCustom(pAryStrCustom, pAryStrCustom->GetSize());
uStartIndex = FILLED_COLUMN_INDEX_MIKE +
rsRowData.uNumMikesToFill + rsRowData.uNumAttendToFill;
for (uAssign = 0; uAssign < rsRowData.uNumCustomToFill; uAssign++, uStartIndex++)
{
if (!IsReadOnly(rsRowData.uGridRow, rsRowData.aryUICustomColIndex[uAssign]))
{
// Only auto assign custom cells that are COMBO (ie: NOT read only)
//if (!AutoAssign(1, uStartIndex, spanAryStrCustom[uAssign],
// rsRowData, rsRowData.aryUICustomColIndex[uAssign]))
if (!AutoAssign(1, uStartIndex, pAryStrCustom[uAssign],
rsRowData, rsRowData.aryUICustomColIndex[uAssign]))
{
bOK = FALSE;
}
}
else
{
// Blank out name
rsRowData.pAryStrNamesThisRow->SetAt(uStartIndex, _T(""));
}
}
}
This is how the main variable (pAryStrCustom
) is defined:
CStringArray* CCreateReportDlg::BuildCustomAssignArray(const ROW_DATA_S &rsRowData)
{
CStringArray *pAryStrCustom = nullptr;
if (rsRowData.uNumCustomToFill > 0)
{
pAryStrCustom =std::make_unique<CStringArray[]>(rsRowData.uNumCustomToFill).release();
ASSERT(pAryStrCustom != nullptr);
if (pAryStrCustom == nullptr)
return nullptr;
const gsl::span spanAryStrCustom(pAryStrCustom, rsRowData.uNumCustomToFill);
const auto iNumAssigns = m_aryPtrAssign.GetSize();
for (INT_PTR iAssign = 0, iUsedAssign = 0; iAssign < iNumAssigns; iAssign++)
{
const CUSTOM_ASSIGN_S* psAssign = static_cast<CUSTOM_ASSIGN_S*>(m_aryPtrAssign.GetAt(iAssign));
if (psAssign != nullptr)
{
if (!psAssign->bExcluded && iUsedAssign < gsl::narrow<INT_PTR>(rsRowData.uNumCustomToFill))
{
spanAryStrCustom[iUsedAssign].Copy(psAssign->aryStrBrothersAll);
iUsedAssign++;
}
}
}
}
return pAryStrCustom;
}
I have debugged my code and I have an array of 5 CStringArrays
. And each of the arrays do have content. But notice I had to comment out some code:
//if (!AutoAssign(1, uStartIndex, spanAryStrCustom[uAssign],
// rsRowData, rsRowData.aryUICustomColIndex[uAssign]))
It dies if I use that spanAryStrCustom
span. Why? Using a legacy array approach to access the data is fine.
This is the offending bit:
spanAryStrCustom[uAssign]
I had to change the way I defined the span:
const gsl::span spanAryStrCustom(pAryStrCustom, rsRowData.uNumCustomToFill);
It was a mistake to use pAryStrCustom->GetSize()
because it is actually an dynamic array of CStringArray
objects. I now realise that using GetSize()
was returning the size of the first array (4
) which was actually making it one smaller than it needed to be (5
).
So using the same UINT
that was used to build the dynamic array was the answer.