[완료]list를 쓰면서 list안의 데이타 지우기!!

tkfkdgody의 이미지

안녕하세요
리스트를 쓰다가 되지 않는게 있어서 글 올립니다.

        static std::list<UserInfo*> m_user;
리스트는 public로 객체를 저장합니다.
따로 함수를 만들어서 함수가 호출되면 위에 리스트에 객체를 저장합니다.
리스트에 객체가 저장되면 아래와 같이 리스트에 있는지 확인하고 있으면 리스트에 쌓인 객체들을
처리하게끔 합니다.
this->DoLogout((*it));

리스트에 객체가 저장됐는지 확인하고 처리하는 부분...

        	Address& add = Address::GetInstance();
		while (!m_user.empty())
		{
			std::list<UserInfo*>::iterator it;
			for ( it = m_user.begin(); it != m_user.end(); it++ )
			{
				printf("id :%d\n", (*it)->ID);
				printf("account :%s\n", (*it)->account);
 
				this->DoLogout((*it));
 
				m_user.erase(it);
 
			}
		}

문제는 위의 리스트에 객체가 저장됐는지 확인하고 처리하는 부분에서 리스트안의 객ㅊ를 처리하고 즉

this->DoLogout((*it));
m_user.erase(it);

위와 같이 리스트안의 객체를 지우고 나서도 포문을 타면서 포문의 작업들을 하면서 아래와 같은 이상한 출력을 하고서
죽어버린다는 것입니다.

제대로 출력될때
id : 1
account : user

프로그램이 죽어버릴때

id : 0
account : !

처음에 DoLogout함수를 타고 그 2번째 DoLogout함수를 타고 나서 m_user.erase(it); <<< 여기에서 죽습니다.

처리할 데이타가 리스트안에 없는걸로 아는데 포문의 루틴을 계속 타면서 죽어버리네요...;;;
잘못한 점이 무엇일까요.. 답변 부탁드리겠습니다..

chadr의 이미지

반복자가 무효화 되는 경우가 몇가지 있습니다. 그중에서 erase와 같은 삭제함수가 그렇습니다.
이런 반복자가 무효화 되는 함수를 이용을 하면 인자로 주어진 반복자는 그 즉시 무효화가 되며
이 반복자를 이용한 어떠한 행동도 의도하지 않는 현상이 일어나게 됩니다.

이런 현상을 방지하기 위해서는 반복자를 새로 받는 수 밖에 없습니다.
일부 몇몇의 stl 구현에서는 erase함수에서 다음 반복자를 리턴하는 경우도 있지만 표준은 아닙니다.

위와 같은 경우에는

 for ( it = m_user.begin(); it != m_user.end(); it++ )
{
printf("id :%d\n", (*it)->ID);
printf("account :%s\n", (*it)->account);
 
this->DoLogout((*it));
}
 
m_user.clear();

라고 하시는게 더 좋을듯 합니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

tkfkdgody의 이미지

답변 감사합니다...
적용해보니 말씀해주신대로 더 좋군요...^.^

반복자가 무효화 된다는게 erase함수가 작동은 하는데 효력이 없다는 말씀이신가요...
흠.. 2번째에는 프로그램 자체가 죽어버리니까 이건 알수 없는 일이 일어난건가요?

정말 감사합니다..

chadr의 이미지

간단하게 반복자를 포인터라고 생각하시면 됩니다.
효력이 없는것 뿐만 아니라 무효화된 반복자를 사용하면 프로그램이 죽습니다.:)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

Fe.head의 이미지

it = m_user.erase(it);

이렇게 한번 바꿔보세요.

-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

chadr의 이미지

그 방법은 표준이 아닌걸로 알고 있습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

Fe.head의 이미지

리스트에서 이방법이 표준이 아닌가요?
표준이라는 말은 없었지만 c++ standard library 책, 이펙티브 STL에 이 내용이 나오던데..
혹시 있으시다면 표준이 아니다라는 링크좀 걸어 주시겠습니까?
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

tkfkdgody의 이미지

두분 다 답변 감사합니다..

즐거운 하루 하루 되세요~~~

tkfkdgody의 이미지

위에 있는 질문들은 std::list에서 쓸 때
m_user.clear();it = m_user.erase(it);
를 쓰는데요 std::map에 있는 여러개의 데이타 중 하나를 삭제할려고
m_map.erase(it);
이런 식으로 쓰고 있었는데 역시나 프로그램이 죽어버리네요..

그래서 clear()은 전체를 다 지우는거니 하나를 지우려면
it = m_map.erase(it);
방식으로 해야 될거 같아서 저렇게 해보니까

Quote:
no matcj for 'operator'...
라고 나오네요..

map의 경우는 어떻게 해야 되나요...

Fe.head의 이미지

m_map.erase(it++);

이렇게 해보세요.
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

tkfkdgody의 이미지

문제는 제가 질문한게 아니였네요..
이 프로그램 만들면서 처음에 했던 에러가 지금 났던거였습니다.
위에 알려주신 아래 코드는 바꿨습니다.
m_map.erase(it++);
빼고 돌려봤는데 문제는 없더군요. 그래도 혹시 무효화함수에 의해 예기치 못한 일이 발생한다고
말씀해주셔서 맘이 놓이지 않아 답변 해주신데로 바꿔놨습니다..

답변 감사합니다..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.