CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Exception when the second list element size =1

  1. #1
    Join Date
    May 2015
    Posts
    303

    Exception when the second list element size =1

    Hi,

    I have the following piece of function. Under the node, there are sul and tdd cells. I try to move them to another node, with two lists, one with sul cells and another with tdd cells.
    Now based on some condition is met, each sul is paired with only one tdd cell.

    I put the following code, but in the second for loop, the exception is thrown. (The scenario i tested is , 2 sul cells and one tdd cell).

    I have shown the line in red. Error is "Cannot decrement begin list iterator"

    Code:
    void UlDlDecoupCellIdentityPlanner::PopulateMultiTechNodePtr2SulTddCellListMap()
    {
    	ILogicalLayerManager&	rLogLayManager  = DataManager::GetInstance().GetLogicalLayer();
    	UserGroupManager&		rUserGrpManager = UserGroupInstance::instance().GetManager();
    
    	ASSERT_ONCE(m_MultiTechNodePtr2SulTddCellListMap.size() == 0);
    
    	// TODO_PRIYA@ SUL to 5g
    	const safemap<int, LP5GCELL>& rCellList = m_rUlDlDecoupCellIdPlannerData.GetSulCellList();
    	m_pProgressDlg->SetCurrentRangeMax((ULONG)rCellList.size() - 1);
    
    	// Make a list of SUL and TDD cells.
    
    //	for (auto& mapObj : rCellList)
    	for(auto& mapObj = rCellList.begin(); mapObj != rCellList.end(); ++mapObj)
    	{
    		const int iCellKey = mapObj->first;
    		const MultiTechCell* pCell = dynamic_cast<const MultiTechCell*>(rLogLayManager.Find(OT_MULTI_TECH_CELL, iCellKey));
    
    		TgNetType eTgNetType = pCell->GetActiveTechnologyMode();
    		const TechCellParams* pFiveGTechCellParams = pCell->GetTechnologyParameters(eTgNetType);
    		const FiveGCellParams* pFiveGParams = dynamic_cast<const FiveGCellParams*>(pFiveGTechCellParams);	ASSERT_ONCE(pFiveGParams);
    		const FiveGCellCarrier* pFiveGCellCarrier = pFiveGParams->GetSingleCarrier();	ASSERT_ONCE(pFiveGCellCarrier);
    		const FiveGCarrier* pFiveGCarrier = pFiveGCellCarrier->Get5GCarrier();
    		IDataManager* pDataManager = IDataManager::Interface();	ASSERT_ONCE(pDataManager);
    		const FiveGFrame* pFiveGFrame = (pFiveGCarrier) ? pFiveGCarrier->Get5gFramePointer(pDataManager) : nullptr;
    
    	//if (!rUserGrpManager.CanModifyObject(*pCell)) continue;
    
    		const auto* pNode = static_cast<const MultiTechNode*>(pCell->GetParent());
    		MultiTechNodePtr2SulTddCellListMapIter iterNode = m_MultiTechNodePtr2SulTddCellListMap.find(pNode);
    
    		if (iterNode == m_MultiTechNodePtr2SulTddCellListMap.end())	// If not seen the node before ...
    		{
    			SulTddCellListMap rSulTddCellList;
    			MultiTechCellConstPtrList rSulCellList;
    			MultiTechCellConstPtrList rTddCellList;
    			if (pFiveGFrame->GetDuplexMode() == FiveGEnums::FiveGDuplexMode::SUL)
    			{
    				rSulTddCellList.sulCellList.push_back(pCell);
    				m_MultiTechNodePtr2SulTddCellListMap.insert((std::make_pair(pNode, rSulTddCellList)));
    			}
    			else if (pFiveGFrame->GetDuplexMode() == FiveGEnums::FiveGDuplexMode::TDD)
    			{
    				rSulTddCellList.tddCellList.push_back(pCell);
    				m_MultiTechNodePtr2SulTddCellListMap.insert((std::make_pair(pNode, rSulTddCellList)));
    			}
    		}
    		else
    		{
    			SulTddCellListMap& rLsit = iterNode->second;	// .. else update the list of child cells for the node
    			if (pFiveGFrame->GetDuplexMode() == FiveGEnums::FiveGDuplexMode::SUL)
    			{
    				rLsit.sulCellList.push_back(pCell);
    			}
    			else if (pFiveGFrame->GetDuplexMode() == FiveGEnums::FiveGDuplexMode::TDD)
    			{
    				rLsit.tddCellList.push_back(pCell);
    			}
    			else
    			{
    				// NOT HANDLED
    			}
    		}
    
    		m_pProgressDlg->IncrementCurrentProgress();
    	}
    
    	for (auto& mapObj : m_MultiTechNodePtr2SulTddCellListMap)
    	{
    		auto nNode = mapObj.first;
    		auto nCellList = mapObj.second;
    		for (auto& sulCell : nCellList.sulCellList)
    		{
    			bool bFirstMatch = false;
    			bool bCanbePaired = false;
    //			for (auto& tddCell : nCellList.tddCellList)
    		    for (auto &tddCell = nCellList.tddCellList.begin(); tddCell != nCellList.tddCellList.end(); ++tddCell)
    			{
    				// If can be paired, add the new list and erase TDD cell
    
    	//			if (CanbePairedBasedOnAzimuth(sulCell,*tddCell))
    				{
    					auto iterNode = m_MultiTechNodePtr2SulTddGUlDlDecoupCellListMap.find(nNode);
    
    					if (iterNode == m_MultiTechNodePtr2SulTddGUlDlDecoupCellListMap.end())
    					{
    						SulTddCellList sulTddCellList;
    
    						SulTddCellListPairMap pairMap;
    
    						pairMap.m_pSulCell = const_cast<MultiTechCell*>(sulCell);
    						pairMap.m_pTddCell = const_cast<MultiTechCell*>(*tddCell);
    
    						sulTddCellList.push_back(pairMap);
    
    						m_MultiTechNodePtr2SulTddGUlDlDecoupCellListMap.insert(make_pair(nNode, sulTddCellList));
    					}
    					else
    					{
    						// else update the list of child cells for the node
    						SulTddCellList& rLsit = iterNode->second;
    
    						SulTddCellListPairMap pairMap;
    
    						pairMap.m_pSulCell = const_cast<MultiTechCell*>(sulCell);
    						pairMap.m_pTddCell = const_cast<MultiTechCell*>(*tddCell);
    
    						rLsit.push_back(pairMap);
    					}
    
    					bCanbePaired = true;
    
    					// Erase the TDD cell as it cannot be paired again
    					tddCell = nCellList.tddCellList.erase(tddCell);  //eraseand go to next(erase will return the next iterator)
    					{
    						--tddCell;  // as it will be add again in for, so we go back one step
    					}
    
    				}
    			}
    			// skip this sul cell.
    			if (bCanbePaired)
    				break;
    		}
    	}
    		
    }
    It will be very helpful, if you can suggest improvements also

    Thank a lot
    pdk
    Last edited by pdk5; June 6th, 2020 at 06:22 AM.

  2. #2
    Join Date
    May 2015
    Posts
    303

    Re: Exception when the second list element size =1

    I also tried to write simple program to check the erase and it is working ok. This one i tried on cygwin. (The above program is in visual studio 19).

    Basically, when the list has only one element, the erase will return the next element . i.e end() . When it-- is done on end () , what happens ?
    In my previous program, i had posted, the erase is returning the begin() . Not sure why ?
    Code:
    int main()
    {
            std::list<int> lst(1, 2);
    
            for(std::list<int>::iterator it = lst.begin(); it != lst.end(); it++)
            {
                    std::cout << *it << "\t";
    
                    if (*it == 2)
                    {
                            it = lst.erase(it);
                            it--;
                    }
             }
    
    
            std::cout << "After : ";
    
            for(std::list<int>::iterator it = lst.begin(); it != lst.end(); it++)
            {
                    std::cout << *it << "\t";
            }
    }
    Last edited by pdk5; June 6th, 2020 at 06:32 AM.

  3. #3
    Join Date
    May 2015
    Posts
    303

    Re: Exception when the second list element size =1

    I found a hack:

    Instead of :
    tddCell--;

    I replaced it with the:
    if (tddCell == nCellList.tddCellList.begin())
    {
    break;
    }
    else
    tddCell--;

    And it works !!!

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,254

    Re: Exception when the second list element size =1

    The way to erase elements from a container is:

    Code:
    include <list>
    #include <iostream>
    
    int main()
    {
    	std::list<int> lst {3, 2};
    
    	for (auto it = lst.begin(); it != lst.end(); ) {
    		std::cout << *it << '\n';
    
    		if (*it == 2)
    			it = lst.erase(it);
    		else
    			++it;
    	}
    
    	std::cout << "\nAfter : ";
    
    	for (auto it = lst.begin(); it != lst.end(); ++it) {
    		std::cout << *it << '\n';
    	}
    }
    Note that the for statement doesn't increment the iterator!

    I found a hack:
    Yes, because of the wrong way you are doing the erase loop! Your for loop is always incrementing the iterator and you are trying to compensate by decrementing the iterator after the erasure! NO. If you erase you don't alter the iterator after the assignment. If you don't erase then you increment the iterator.
    Last edited by 2kaud; June 6th, 2020 at 07:07 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.3)

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,254

    Re: Exception when the second list element size =1

    Using very long names within the code makes the code very hard to read and understand! Yes, names should be meaningful but also easy to read. IMO I suggest a limit of about 15.

    Using structured bindings can help. Instead of:

    Code:
    for (auto& mapObj : m_MultiTechNodePtr2SulTddCellListMap) {
    	auto nNode = mapObj.first;
    	auto nCellList = mapObj.second;
    use:

    Code:
    for (auto& [nNode, nCellList] : m_MultiTechNodePtr2SulTddCellListMap) 	{
    Last edited by 2kaud; June 6th, 2020 at 07:27 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.3)

  6. #6
    Join Date
    May 2015
    Posts
    303

    Re: Exception when the second list element size =1

    Thanks a lot kaud. Very helpful.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,254

    Re: Exception when the second list element size =1

    i had posted, the erase is returning the begin()
    It is returning end(). However:

    - for 1 or more elements, end() returns 1 past the last element
    - for no elements, end() returns begin()

    This is so that the standard iterator for statement:

    Code:
    for (auto iter = cont.begin(); iter != cont.end(); ++iter)
    works when the container is empty as well as when it has elements.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.3)

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,356

    Re: Exception when the second list element size =1

    Quote Originally Posted by 2kaud View Post
    Using very long names within the code makes the code very hard to read and understand! Yes, names should be meaningful but also easy to read. IMO I suggest a limit of about 15.
    Agreed. I'm a fan of descriptive variables and method names vs. one or two characters, these have gone too far the other way.

  9. #9
    Join Date
    May 2015
    Posts
    303

    Re: Exception when the second list element size =1

    Thanks a lot kaud for explaining. I am grateful to get suggestions here, I know I need to work on programming skills. I appreciate your patience and willingness to help . Thanks a lot again.
    @Arjay: yes, names are bit far descriptive, as I am just trying to follow template of legacy code.

    Thanks a lot again, for inputs, helpful for me to improve.

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,254

    Re: Exception when the second list element size =1

    Note that .insert() within an iterator loop can have a similar - but different- issue and needs to be considered on a case-by-case basis depending upon the container type and location of insertion.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.3)

  11. #11
    Join Date
    May 2015
    Posts
    303

    Re: Exception when the second list element size =1

    Thanks a lot kaud, for pointing out that.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)