【问题标题】:warning C6262: Function uses '27688' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap警告 C6262:函数使用 '27688' 字节的堆栈:超过 /analyze:stacksize '16384'。考虑将一些数据移动到堆中
【发布时间】:2017-05-11 00:06:33
【问题描述】:

我已经阅读了一些关于这个问题的问题和主题。例如:

Warning message regarding stack size

但我无法真正弄清楚如何在方法中隔离问题:

void CCreateReportDlg::ReadOptions()
{
    CHeadingsDlg            dlgHeadings(this);
    COptionsDlg             dlgOptions(this);
    CBrothersDlg            dlgBrothers(this, FALSE);
    CAutoAssignSettingsDlg  dlgAssign(this);
    CString                 strSection = theApp.GetActiveScheduleSection(_T("Options"));

    // headings
    m_strReportTitle = dlgHeadings.GetReportTitle();
    dlgHeadings.GetHeadings(m_aryStrHeading);

    m_eReportMode = dlgOptions.GetReportMode();

    // brother data
    dlgBrothers.GetBrotherData(SOUND, m_aryStrSoundWT, m_aryStrSoundSM, TRUE);
    dlgBrothers.GetBrotherData(PLATFORM, m_aryStrPlatformWT, m_aryStrPlatformSM, TRUE);
    dlgBrothers.GetBrotherData(MIKE, m_aryStrMikeWT, m_aryStrMikeSM, TRUE);
    dlgBrothers.GetBrotherData(ATTENDANT, m_aryStrAttendWT, m_aryStrAttendSM, TRUE);
    dlgBrothers.GetBrotherData(SOUND, m_aryStrBroSoundAll, TRUE);
    dlgBrothers.GetBrotherData(PLATFORM, m_aryStrBroPlatformAll, TRUE);
    dlgBrothers.GetBrotherData(MIKE, m_aryStrBroMikeAll, TRUE);
    dlgBrothers.GetBrotherData(ATTENDANT, m_aryStrBroAttendAll, TRUE);

    CCustomAssignManagerDlg::GetCustomAssignData(m_aryPtrAssign, TRUE, ASSIGN_SORT_HEADING);

    if(m_eReportMode != MODE_MEETING)
    {
        // We need to update the arrays to only include the brothers that are available
        // on both days (so the two arrays become identical)
        ModifyBrotherArrays();
    }

    dlgBrothers.GetBrotherData(m_cbBrother);

    // We need an array of unique names
    // (without first to entries in combo)
    // Used during printing and exporting (multi highlight)
    dlgBrothers.GetBrotherData(m_aryStrNames);
    CBrothersDlg::SortArray(m_aryStrNames);

    // options
    m_bExcludePlatformColumn = dlgOptions.ExcludePlatformColumn();
    m_bExcludePlatformMikeColumn = dlgOptions.ExcludePlatformMikeColumn();
    m_bExcludeAttendColumn = dlgOptions.ExcludeAttendantColumn();

    m_iNumMikeUsers = dlgOptions.GetNumMikeUsers();
    m_iNumSoundUsers = dlgOptions.GetNumSoundUsers();
    m_iNumAttendUsers = dlgOptions.GetNumAttendants();

    dlgOptions.GetMeetingDays(m_iDayWT, m_iDaySM, m_iDayWeek);
    m_iDayWT++;
    m_iDaySM++;
    m_iDayWeek++;

    dlgOptions.GetCustomDateOptions(m_bCustomDate, m_strDateFormat);

    m_bAvoidBack2Back = dlgAssign.AvoidBack2Back();
    m_bCheckForConflicts = dlgAssign.CheckForConflicts();
    m_bSelectNames = dlgAssign.SelectNames();

    theApp.ReadDateMapData(m_mapSPtrBroDates);

    m_bShowNotes = (BOOL)theApp.GetNumberSetting(strSection, _T("ShowNotes"), (int)TRUE);
    m_bNoticeBoard = (BOOL)theApp.GetNumberSetting(strSection, _T("NoticeBoard"), (int)FALSE);

    dlgOptions.ReadAssignStatesInfoEx(m_byAryAutoAssignStates);
}

我知道我可以调整编译器并增加堆栈大小以抑制错误。

但是在我的方法中识别路径原因的基本方法是什么?

第一组变量是CStringArray。然后是CPtrArray 对象,类型为CUSTOM_ASSIGN_S

typedef struct tagCustomAssignment
{
    int     iIndex;
    CString     strDescription;
    CString     strHeading;
    BOOL        bExcluded;
    CStringArray    aryStrBrothersAll;
    CStringArray    aryStrBrothersWT;
    CStringArray    aryStrBrothersSM;

    BOOL        bIncludeWT;
    BOOL        bIncludeTMS;

    BOOL        bFixed;
    int     iFixedType;

} CUSTOM_ASSIGN_S;

同样,上述结构的成员都不是大数组[xxx]。唯一值得注意的方法是ReadDateMapData,它读取存档并填充另一个地图。

但如前所述,我不知道如何隔离问题。没有定义大型数组。一两个TCHAR file[_MAXPATH];,仅此而已。其余类如CStringArrayCPtrArray 等。

提前谢谢你。

更新

根据提供的 cmets,我能够确定即使只是顶部的变量声明:

CHeadingsDlg            dlgHeadings(this);
COptionsDlg             dlgOptions(this);
CBrothersDlg            dlgBrothers(this, FALSE);
CAutoAssignSettingsDlg  dlgAssign(this);
CString                 strSection = theApp.GetActiveScheduleSection(_T("Options"));

会导致它的堆栈大小从 18072 开始。

【问题讨论】:

  • 如果通过查看堆栈变量(具有大型 c 数组的类?)不明显,我倾向于执行“二分查找”消除过程并消除一半代码(注释掉,使用#if/#endif) 并反复找出问题所在。有时它不仅仅是 1 行,而是很多时候。这种方法有助于查明问题所在的那行(或几行)代码。
  • @franji1我对堆栈大小的猜测并不感到惊讶,因为这些是与映射到变量等的控件的对话。我声明一个对话实例只是为了从注册表中读取设置(通过相应的对话公共方法)。

标签: mfc code-analysis stack-size


【解决方案1】:

我在这个类中的主要变量实际上是 dialog 对象,由于所有成员变量等原因,这些对象非常大。

我使用这些对话的原因是通过使用它们的公共方法来访问应用程序设置。

通过将这些对话声明更改为 new / delete 并调整代码,我不再收到堆栈大小警告:

void CCreateReportDlg::ReadOptions()
{
    CHeadingsDlg *pDlgHeadings = new CHeadingsDlg(this);
    if (pDlgHeadings != NULL)
    {
        m_strReportTitle = pDlgHeadings->GetReportTitle();
        pDlgHeadings->GetHeadings(m_aryStrHeading);

        delete pDlgHeadings;
    }

    COptionsDlg *pDlgOptions = new COptionsDlg(this);
    if (pDlgOptions != NULL)
    {
        m_eReportMode = pDlgOptions->GetReportMode();
        m_bExcludePlatformColumn = pDlgOptions->ExcludePlatformColumn();
        m_bExcludePlatformMikeColumn = pDlgOptions->ExcludePlatformMikeColumn();
        m_bExcludeAttendColumn = pDlgOptions->ExcludeAttendantColumn();
        m_iNumMikeUsers = pDlgOptions->GetNumMikeUsers();
        m_iNumSoundUsers = pDlgOptions->GetNumSoundUsers();
        m_iNumAttendUsers = pDlgOptions->GetNumAttendants();

        pDlgOptions->ReadAssignStatesInfoEx(m_byAryAutoAssignStates);
        pDlgOptions->GetCustomDateOptions(m_bCustomDate, m_strDateFormat);

        pDlgOptions->GetMeetingDays(m_iDayWT, m_iDaySM, m_iDayWeek);
        m_iDayWT++;
        m_iDaySM++;
        m_iDayWeek++;

        delete pDlgOptions;
    }

    CBrothersDlg *pDlgBrothers = new CBrothersDlg(this, FALSE);
    if (pDlgBrothers != NULL)
    {
        pDlgBrothers->GetBrotherData(SOUND, m_aryStrSoundWT, m_aryStrSoundSM, TRUE);
        pDlgBrothers->GetBrotherData(PLATFORM, m_aryStrPlatformWT, m_aryStrPlatformSM, TRUE);
        pDlgBrothers->GetBrotherData(MIKE, m_aryStrMikeWT, m_aryStrMikeSM, TRUE);
        pDlgBrothers->GetBrotherData(ATTENDANT, m_aryStrAttendWT, m_aryStrAttendSM, TRUE);
        pDlgBrothers->GetBrotherData(SOUND, m_aryStrBroSoundAll, TRUE);
        pDlgBrothers->GetBrotherData(PLATFORM, m_aryStrBroPlatformAll, TRUE);
        pDlgBrothers->GetBrotherData(MIKE, m_aryStrBroMikeAll, TRUE);
        pDlgBrothers->GetBrotherData(ATTENDANT, m_aryStrBroAttendAll, TRUE);
        pDlgBrothers->GetBrotherData(m_cbBrother);

        // We need an array of unique names (without first two entries in combo)
        // Used during printing and exporting (multi highlight)
        pDlgBrothers->GetBrotherData(m_aryStrNames);
        CBrothersDlg::SortArray(m_aryStrNames);

        delete pDlgBrothers;
    }

    CAutoAssignSettingsDlg *pDlgAssign = new CAutoAssignSettingsDlg(this);
    if (pDlgAssign != NULL)
    {
        m_bAvoidBack2Back = pDlgAssign->AvoidBack2Back();
        m_bCheckForConflicts = pDlgAssign->CheckForConflicts();
        m_bSelectNames = pDlgAssign->SelectNames();

        delete pDlgAssign;
    }

    CCustomAssignManagerDlg::GetCustomAssignData(m_aryPtrAssign, TRUE, ASSIGN_SORT_HEADING);

    if(m_eReportMode != MODE_MEETING)
    {
        // We need to update the arrays to only include the brothers that are available
        // on both days (so the two arrays become identical)
        ModifyBrotherArrays();
    }

    theApp.ReadDateMapData(m_mapSPtrBroDates);

    CString strSection = theApp.GetActiveScheduleSection(_T("Options"));

    m_bShowNotes = (BOOL)theApp.GetNumberSetting(strSection, _T("ShowNotes"), (int)TRUE);
    m_bNoticeBoard = (BOOL)theApp.GetNumberSetting(strSection, _T("NoticeBoard"), (int)FALSE);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多