将 gsl::span 与 CStringArray 对象的动态列表一起使用时出现问题导致中止
Problem using gsl::span with a dynamic list of CStringArray objects is causing a abort
查看这段代码:
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(""));
}
}
}
主变量 (pAryStrCustom
) 是这样定义的:
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;
}
我调试了我的代码,我有一个 5 CStringArrays
的数组。每个数组都有内容。但请注意,我必须注释掉一些代码:
//if (!AutoAssign(1, uStartIndex, spanAryStrCustom[uAssign],
// rsRowData, rsRowData.aryUICustomColIndex[uAssign]))
如果我使用 spanAryStrCustom
跨度,它就会死掉。为什么?使用遗留数组方法访问数据很好。
这是有问题的位:
spanAryStrCustom[uAssign]
我不得不改变定义跨度的方式:
const gsl::span spanAryStrCustom(pAryStrCustom, rsRowData.uNumCustomToFill);
使用 pAryStrCustom->GetSize()
是错误的,因为它实际上是一个 动态 CStringArray
对象数组.我现在意识到使用 GetSize()
返回第一个数组 (4
) 的大小,这实际上使它比需要的小一个 (5
).
所以使用与构建动态数组相同的 UINT
就是答案。
查看这段代码:
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(""));
}
}
}
主变量 (pAryStrCustom
) 是这样定义的:
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;
}
我调试了我的代码,我有一个 5 CStringArrays
的数组。每个数组都有内容。但请注意,我必须注释掉一些代码:
//if (!AutoAssign(1, uStartIndex, spanAryStrCustom[uAssign],
// rsRowData, rsRowData.aryUICustomColIndex[uAssign]))
如果我使用 spanAryStrCustom
跨度,它就会死掉。为什么?使用遗留数组方法访问数据很好。
这是有问题的位:
spanAryStrCustom[uAssign]
我不得不改变定义跨度的方式:
const gsl::span spanAryStrCustom(pAryStrCustom, rsRowData.uNumCustomToFill);
使用 pAryStrCustom->GetSize()
是错误的,因为它实际上是一个 动态 CStringArray
对象数组.我现在意识到使用 GetSize()
返回第一个数组 (4
) 的大小,这实际上使它比需要的小一个 (5
).
所以使用与构建动态数组相同的 UINT
就是答案。