STL list와 구조체 사용에 대해 질문 드려요~

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
비회원

STL list와 구조체 사용에 대해 질문 드려요~

Post by 비회원 »

STL에 따로 정의한 구조체에 대한 리스트를 만들었습니다.

struct SDataInfo;
typedef std::list<SDataInfo> List_Info;
typedef std::list<SDataInfo> Iter_Info;

struct SDataInfo
{
IMyDataID* ID;
IMyData* Data;
}

class Data
{
...

List_Info m_List;
Iter_Info m_Iter;
...

}


void Data::Function()
{
m_Iter = m_List.begin();
for(; m_Iter != m_List.end(); ++m_Iter)
{
....
}
}


여기서 Function()안에 m_Iter = m_List.begin()을 지난뒤에
적절한 값이 들어갈 것으로 기대했으나,
m_Iter가 가리키고 있는 ID와 Data에는 0xcccccccc만 뜹니다.
(리스트의 사이즈를 확인해보니 확실히 값이 적재되어 있습니다.)

어떻게 해야지 iterator가 제대로 된 값을 가리키게 할 수 있을까요??


그리고 STL에서 for문 예제를 보니 대체로 ++m_Iter처럼 선증가로 표기를 하던데
m_Iter++ 로 하지 않는 이유가 무엇인가요??

고수님들의 답변 부탁드립니다~
mika
Posts: 537
Joined: 2005-01-17 22:42

Post by mika »

위 코드만 봐서는 모르겠네요. 리스트에 값을 추가하는 부분도 보여주세요. ^^

위 코드만으로 짐작할 수 있는 바는 값이 0xcccccccc인 것으로 보아 SDataInfo 개체가 리스트에 추가는 되었으나 멤버 변수들에 제대로된 값이 할당되지 않았다는 것 정도겠네요. list에 값을 추가한다고 해당 값을 초기화까지 해주지는 않습니다. 직접 해주셔야죠.

그리고 typedef std::list<SDataInfo> Iter_Info; 는 오타로 보이는데요, typedef std::list<SDataInfo>::iterator Iter_Info; 겠죠? 그런데 굳이 이터레이터를 멤버 변수로 들고 있을 필요는 안 보이는데요..

저라면

Code: Select all

for (List_Info::iterator iter = m_List.begin(); iter != m_List.end(); ++iter)
와 같이 쓰겠습니다. ^^

마지막으로 ++iter와 iter++는 ++의 동작원리를 생각해 보시면 쉽게 유추 가능하실 것 같네요. 전자가 효율이 높습니다. (내장 타입의 경우에는 전위냐 후위냐에 대해 말들이 많은데요, 내장 타입이 아닌 경우에는 지켜주는 것이 옳다고 생각합니다.)

하지만 iter++가 필요한 경우도 물론 있겠죠? 상황에 맞게 쓰면 되겠습니다.
비회원

리스트 데이터 삽입 부분 올립니다.

Post by 비회원 »

말씀하신 데이터 삽입부분은 다음과 같습니다.

Code: Select all

BOOL   CData::InsertData(IMyDataID* pID, IMyData* pData)
{
     SDataInfo* t_OutInfo;
     t_OutInfo.ID = pID;
     t_OutInfo.Data = pData;
    
     m_ListChatting.push_back(&t_OutInfo);

     ...

     return TRUE;
} 

말씀을 들어보니 iterator를 멤버로 둘 필요가 없겠네요.
STL이 아직 익숙하지가 않아서요 ^^;

그리고 제가 아직 부족해서 그런지 전위를 사용할 때 어떤 효율성이 있는지
딱 와닿지가 않습니다.

오히려 전위증가를 사용하면 리스트의 맨 첫번째 노드를 가리키지 못하고
두번째 노드부터 가리키게 되는 것 아닌가요??
(시작부터 이미 증가하고 가리키니까요;;)

지적 부탁드립니다~
Zeprod
Posts: 480
Joined: 2006-11-04 16:24
Location: Creaty Networks
Contact:

Post by Zeprod »

전위 후위의 성능차이는 연산이 일어나는 시점에 달려있습니다.

후위의 경우에는 한번 연산이 뒤에 증가를 시켜야하므로, 증가를 해야한다는 것을 기억해야만 합니다.
전위의 경우, 그런 기억이 필요없이 바로 증가시키면 끝이지요.

for문의 경우 전위, 후위의 기능상 차이는 없습니다. for문의 인자로 들어가는 3번째 항목은, 각 루프의 사이에만 동작하며, 최초 초기화는 첫번째 인자가 실행되지요.

그래서 for문에 전위연산자가 많이 쓰이는 것입니다.
세상이 기다리는 나만의 SHOW!
----------------------------------------------
Zeprod 홈 : http://Zeprod.org
Project. Creaty : http://Creaty.net/
Creaty 게임제작 커뮤니티 : http://Creaty.net/game/
----------------------------------------------
비회원

답변 감사합니다.

Post by 비회원 »

답변 감사합니다~

전위 후위간의 성능상의 차이에 대해서 잘 이해되었습니다.

그런데 여전히 리스트에서 얻어온 iterator 값이 0xcccccccc인 점이 해결되지 않습니다.

왜 이럴까요~?? ㅠㅠ
bangwall
Posts: 23
Joined: 2006-09-21 00:15

Post by bangwall »

stl에서 전위와 후위의 차이는 stl이 구현된 코드를 보면 이해가 편하실겁니다.
_Myt_iter& operator++()
{ // preincrement
++(*(_Mybase_iter *)this);
return (*this);
}


_Myt_iter operator++(int)
{ // postincrement
_Myt_iter _Tmp = *this;
++*this;
return (_Tmp);
}

여기서 보이시듯이 후위연산자는 _Myt_iter _Tmp = *this; 템프 변수를 하나 할당하고 연산하게 되어있습니다. 그러므로 후위보다 전위가 빠르다는 것을 알수 있습니다. ^^
bangwall
Posts: 23
Joined: 2006-09-21 00:15

Post by bangwall »

아. 그리고 stl안에 들어있는 구조체의 값이 잘못된 것은 구조체의 값이 pointer이기 때문이 아닐까 합니다. stl에 인서트를하지만 해당 구조체는 그 값을 가리키는 pointer이므로 이 값이 해제되었거나 한다면 stl의 구조체의 값은 dead pointer일수 밖에 없겠죠.

struct SDataInfo
{
IMyDataID* ID;
IMyData* Data;
}

이 부분을
struct SDataInfo
{
IMyDataID ID;
IMyData Data;
}
이렇게 하고 테스트해보시기 바랍니다.
gal_yong
Posts: 43
Joined: 2005-04-01 14:47

Re: STL list와 구조체 사용에 대해 질문 드려요~

Post by gal_yong »

비회원 wrote:
struct SDataInfo
{
IMyDataID* ID;
IMyData* Data;
}
포인터 변수들(ID, Data)을 초기화 하지 않으셨으면 0xcccccccc뜨는게
정상인 것 같습니다.

insert하기 전,후에

포인터 변수에 값을 할당하시면 될 것 같습니다.
열심히 배우고
열심히 생각하고
열심히 만들자
http://blog.naver.com/gal_yong.do
비회원

답변 감사합니다.

Post by 비회원 »

bangwall, gal_yong님 답변 감사합니다.

덕분에 전위 후위 연산자도 잘 이해가 되었습니다.

그러고보니 포인터를 초기화 해주지도 않았고, dead pointer의 위험도 남겨둔 것 같네요. ^^;

감사합니다~ ^^
비회원

소스만 보면 선언에 문제가 있습니다.

Post by 비회원 »

struct SDataInfo;
typedef std::list<SDataInfo> List_Info;
typedef std::list<SDataInfo> Iter_Info;

struct SDataInfo;
typedef std::list<SDataInfo> List_Info;
typedef std::list<SDataInfo>::iterator Iter_Info;
thisisone
Posts: 147
Joined: 2007-07-15 13:53
Location: 줄진

Post by thisisone »

그러고보니 포인터를 초기화 해주지도 않았고, dead pointer의 위험도 남겨둔 것 같네요. ^^;
포인터 초기화 문제가 아닌거 같아서 답변 올려봅니다.

Code: Select all

     extern std::list<SDataInfo> m_ListChatting;  //이런 선언이겟죠?
     SDataInfo* t_OutInfo; // t_OutInfo = 0xcccccccc 가 들어갑니다.(주의하세요)
     t_OutInfo.ID = pID;
     t_OutInfo.Data = pData;
     m_ListChatting.push_back(&t_OutInfo); // 지역변수의 주소를 넣으셨네요?
아래처럼 고치세요.

Code: Select all

     extern std::list<SDataInfo> m_ListChatting;  //이렇게 고쳐야될꺼 같군요
     SDataInfo t_OutInfo;
     t_OutInfo.ID = pID;
     t_OutInfo.Data = pData;
     m_ListChatting.push_back(t_OutInfo);
이렇게 되도록 m_ListChatting 의 타입을 수정하세요.
퇴근후 섭다
Locked