将 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 就是答案。