warning C6262: Function uses '27688' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap

Andrew Truckle picture Andrew Truckle · Dec 26, 2016 · Viewed 8.9k times · Source

I have read a few questions and topics on this issue. For example:

Warning message regarding stack size

But I can't really work out how I am to isolate the issue in the method:

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);
}

I know I can adjust the compiler and increase the stacksize to supress the error.

But what is the basic approach to identifying the route cause in my method?

The first bunch of variables are CStringArray. Then it is followed by a CPtrArray of objects, of type 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;

Again, none of the members of the above structure are large arrays [xxx]. The only other notable method is ReadDateMapData that reads an archive and fills another map.

But as mentioned, I don't know how to go about isolating the issue. There are no large arrays being define. One or two TCHAR file[_MAXPATH]; but that is about it. The rest of classes like CStringArray or CPtrArray etc..

Thank you in advance.

Update

Based on the comments provided I was able to establish that even just the variable declarations at the top:

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

Would cause it to have a stack size of 18072 to begin with.

Answer

Andrew Truckle picture Andrew Truckle · Dec 26, 2016

My main variables in this class were actually dialog objects which understandably are quite large due to all the member variables etc..

The reason I was using these dialogues was to gain access to application settings by using their public methods.

By changing these dialogue declarations to new / delete and adjusting the code I no longer get the stack size warning:

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);
}