insert 함수를 오버라이딩 했는데, 삽입시 약간의 문제가 발생합니다.

dltkddyd의 이미지

	siterator insert(siterator position, const value_type& val) {
		if(position.pointer()==NULL) {return NULL;}
		if(convertItToIdx(position)==-1) {
			return NULL;
		}
		if(deque<PTRTYPE>::size()==0) {return NULL;}
		ssize_type num=&(*this)[deque<PTRTYPE>::size()-1]-position.pointer()+1;
		ssize_type idx=position.pointer()-&(*this)[0];
cout<<"idx  "<<idx<<"  num  "<<num<<endl;//test
		deque<PTRTYPE>::resize(deque<PTRTYPE>::size()+1);
cout<<deque<PTRTYPE>::size()<<endl;//test
		memmove(&(*this)[idx+1], &(*this)[idx],sizeof(value_type)*num);//이 부분에서 일단 제대로 옮겨지지 않습니다.
		memset(&(*this)[idx],0,sizeof(value_type));//그리고 이걸로 포인터의 연결고리를 끊으려 했는데(이중 커럽션을 방지하기 위해), 마지막에 double corruption 오류가 발생합니다.
		//clear((*this)[idx]);
 
		(*this)[idx]=val;
cout<<"insert 1"<<endl;//test
		return &(*this)[idx];
	}

이 문제 어떻게 해결해야 하나요?

추후 더 살펴보니 이 문제가 operator=에 영향을 또 주는군요. 대입연산자는 다음과 같이 정의했습니다.

	sdeque<value_type>& operator=(  const typename senable_if<is_sdeque<typename senable_if<!is_ssdeque<type>::value,type>::type2>::value,type>::type2& right  ) {//This copys deeply in case of 1 dimession
		if(deque<PTRTYPE>::size()!=0) {
			deque<PTRTYPE>::clear();
		}
		deque<PTRTYPE>::resize(right.size());
		if(is_class<type::value_type>::value==0) {
			memcpy(  &(*this)[0], &right[0], sizeof(value_type)*right.size()  );//trouble
		}
		else {
			for(unsigned long int i=0;i<right.size();i++) {
				(*this)[i]=right[i];//trouble
			}
		}
		return *this;
	}

그리고 main은 다음과 같고요.

int main() {
	sdeque<sdeque<unsigned long int>> obj33(3,2);
	obj33(
		2,4,6,8,10,12
	);
 
	sdeque<unsigned long int> obj34(2);
	obj34(25,26);
	obj33.insertA(obj33.end()-1,obj34);//여기서 문제가 발생하기 시작해서
	cout<<obj33.size()<<endl;
	for(unsigned long int i=0;i<obj33.size();i++) {
		for(unsigned long int j=0;j<obj33[i].size();j++) {
			cout<<obj33[i][j]<<"  ";
		}
	}
	return 0;
}

그러고 보니 질문할 내용의 코드를 제대로 올리지 않았었군요. 이거 새롭게 편집해서 올린 내용입니다.

kukyakya의 이미지

에러가 날 때마다 하나하나 질문 다시기 전에 디버거 사용 방법을 익히시길 추천합니다.

그리고, 사람들이 답글을 달면 좀 읽고 생각해보셨으면 좋겠습니다.

dltkddyd의 이미지

그 질문의 본질이 무엇인지 아시고 답변 주셨으면 좋겠습니다.
과연 내부의 포인터가 무엇이냐는 내용이 포함된 질문이었습니다. 뭔가 어긋나고 있다고 추정되는데, 그게 경험이 부족한 고로 질문드린 겁니다. 전의 내용하고는 다른 질문이었습니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

kukyakya의 이미지

그러니까 디버거를 쓰시라는 겁니다. 뭔가 어긋나고 있다고 추정만 하고 질문하지 마시구요.

지금까지 올리신 질문 중에 상당수의 질문이 디버거를 돌려봤으면 올리지 않으셨을 질문으로 보입니다.
디버거를 돌려봤으면 '왜 이렇게 동작하나요?'의 질문이 올라와야 정상이지 '왜 에러가 나나요?'의 질문이 올라올수는 없거든요.

아마도 지금껏 질문에 원하는 대답을 얻으셨던 적이 별로 없으셨지 싶은데, 왜 그런지 한번쯤 생각해보셨으면 좋겠습니다.

dltkddyd의 이미지

지금의 답변 글 빼고는 원하는 답변들을 하시더군요. 그리고 제가 짐작했던(확신이 서지 않아서 올린 질문글) 것과 같은 답변이 올라온 적도 있었고요. 디버거 돌린다고 딱히 오류가 원지를 알 수가 없죠. 디버거가 오류가 발생한 지점만 알려주지, 뭐가 문제인지를 알려주는 것은 아니죠. 이건 정말 답답한 디버거입니다. 디버거로 찾을 수 있는 문제라면 디버거로 찾아야겠지만, 디버거가 알려주는 것이라는 너무 제한적입니다. 결국 원인은 본인이 찾아야 되는 거고요. 이거 돌렸어도 딱히 뭐가 문제인지 알 수가 없군요. 제가 만들지 않은 코드도 나오고. 머리만 복잡해지는 듯합니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

kaeri17의 이미지

그럼 그 머리 복잡한것을 왜 다른사람에게 전가하나요? 그런거에 머리가 복잡해 진다면 님이 제대로 C++공부를 안했다는 뜻이죠. 만약 C++을 제대로 알고 있고, 그 상태에서 디버깅을 한다면 최소한 문제가 뭔지는 알고 질문을 해야하는겁니다. 질문들 계속 보고 있다 보면 C++기본 개념을 잘 이해 못하시고 계신 상태에서 자꾸 이상한 프로그램을 짜려고 하니 문제가 발생하는 것 같습니다.
C++기본서부터 다시 보시고, The C++ programming language라던가, Effective C++이라던가 정도는 보시고 다시 오시면 친절한 답변이 달릴거라 기대합니다. 저도 글쓴분이 질문하신 그에 답변 몇번 달았지만 그건 그냥 지나가던 길에 친절을 베푼 정도지, 전혀 같이 고민해서 답변을 다는 수준은 아니었습니다. 그런데 질문 수준이 딱 초급자 수준을 몇달동안 벗어나지 못한다면, 아직 답변 다는 분들이 매우 친절하신겁니다.

dltkddyd의 이미지

님이 답변 단 글 기억이 안 나는데요. 기억이 안 나는 것인지, 님이 달지 않은 것인지? 그리고 전가한 적 없습니다. 답변 달기 싫으면 답변 안 달면 그만인 것이죠? 질문과 답은 상호적인 것이지 누가 누구에게 일방적으로 도움을 주는 것이라고만 생각하지 않기에 드리는 말씀입니다. 전혀 쌍방향적이지 않은 사고방식을 가지셨군요. 실력이 없으니 답변 할 건더기도 없겠군요.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

kaeri17의 이미지

아.. 이 답글이 보니 짜증이 마구 나네요. 누가 누구에게 일방적으로 도움을 주게 만든건 님 자신입니다. C++ 조금이라도 아는 사람들은 님이 저런식으로 insert를 오버라이딩 하려는거 보면 그냥 뒷골이 땡기게 됩니다. 그거 참고 답글 달아주는 사람들이 대단한거고, 계속 저런식으로 쓰지 말라고 하는데 끝까지 혼자 저렇게 구현하면서 계속 질문만 양산하고 있는 사람이 님 자신이라고요.
그리고 문법책 다시 보라고 조언도 하고, 읽을 책 추천도 해 주었는데 이런말 들으니 정말 싫네요. 혼자 잘 사시길 바랍니다.

익명 사용자의 이미지

이분글에 꾸준히 답글다는 분들 참 대단하신듯.

dltkddyd의 이미지

문제가 뭔지 아십니까? 알고 이런 말을 하는건지, 모르니까 이런 식으로 얼버무리는 건지 궁금한데요? 저런 식으로 표준을 오버라이딩 하지 말라는 충고는 들었습니다. 그런데 만약 저 insert 함수를 insert가 아닌 다른 insertA 라는 식으로 이름을 바꾸었을 때에도 동일한 문제가 발생합니다. 설사 멤버로 컨테이너 객체를 둔다 할지라도 memset, memmove를 사용하면 저런 동일한 문제가 생깁니다. 이 문제는 충고를 주셨던 문제하고는 다른 문제로 보이는데요.
답변주신대로 디버거 해봤더니 조금 문제가 있는 것으로 보이는 부분이 나오긴 나오더군요.
마지막 부분에서

return 0;

이 두 번 반복됩니다. 또 다른 문제가 있는지는 디버거 봐야 알 것 같습니다. 분명 return 0은 한 번 언급했는데요.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

dltkddyd의 이미지

지금은 또 실행도중에 중지되네요.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

jick의 이미지

http://www.cplusplus.com/reference/deque/deque/

> But, unlike vectors, deques are not guaranteed to store all its elements in contiguous storage locations: accessing elements in a deque by offsetting a pointer to another element causes undefined behavior.

그러니까 deque에 저장된 element의 주소를 이용해서 memmove를 하는 것은 정의되지 않은 동작입니다.

(보충): 심지어 deque가 아닌 vector라 해도 memmove/memcpy로 내용을 옮기는 것은 element type이 POD (plain old data)일 경우에만 가능합니다. (이 부분은 제가 전문가가 아니라서 용어가 부정확할 수도 있는데, 간단히 말하면 int, double, 포인터, 기타 이들만을 이용한 struct까지는 가능하지만 object를 생성/해제할 때 생성자/소멸자를 부르는 모든 클래스는 (다른 deque/vector 포함) 이런 사용이 불가능합니다. string만 해도 이런 식으로 쓸 때 프로그램이 제대로 동작할 거라는 보장이 없습니다.)

jick의 이미지

Corruption이란 건 프로그램에 버그가 있어서 덮어써서는 안되는 메모리를 덮어썼을 때 쓰는 표현입니다. 따라서 double corruption이란 말은 의미가 없으므로 (메모리를 한번 깨먹으나 두번 깨먹으나...) 일반적으로 쓰지 않습니다.

dltkddyd의 이미지

offset을 통해 계산한 idx와 num은 정확히 계산이 됩니다. 그렇다면 문제는 저 idx와 num 때문에 memmove에 이상이 발생하는 것이 아니라 memmove에서 이상이 발생하는 것이라는 말씀이시죠? memmove를 삼가해야 겠군요. 감사합니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

jick의 이미지

아직 C와 C++의 철학에 익숙하지 않으신 것 같은데, 이 언어들은 "프로그램을 제대로 짰을 때 제대로 된 결과가 나온다"만 보장하지 "틀리게 짰을 때 틀린 결과가 나온다"를 절대 보장하지 않습니다.

다시 말해 idx와 num이 "정확히" 계산이 되었다는 느낌이 든다면 그건 그냥 오늘 운이 좋은 겁니다.
(아니, 버그가 있는 코드를 버그를 발견하지 못하고 넘어가는 셈이니 운이 나쁘다고 해야 할지도...)

#include <deque>
#include <stdio.h>
 
using namespace std;
 
int main()
{
  deque<int> d;
  for (int i = 0; i < 1000000; i++) {
    d.push_back(i);
    if (&d[i] != (&d[0] + i)) {
      printf("%d: Not contiguous!!!\n", i);
      return 1;
    }
  }
  return 0;
}
 
실행결과 (Mac OS X):
65536: Not contiguous!!!
pynoos의 이미지

명세와 구현의 차이를 염두에 두고 공부해 보세요. 중요합니다.
명세에서 정의되지 않은 것은 구현마다 달라질 수 있습니다.
이왕이면, 다른 환경의 컴파일러나 라이브러리들에서도 돌려서 직접 비교해보세요.

익명 사용자의 이미지

모르면서 아는척이 너무 심해서 별로 대답해주고 싶지 않네요.
정상적인 대답을 해줘도 반발만 하니 답이 없습니다.

dltkddyd의 이미지

익명성 뒤에 숨어서 함부로 험담하지 말기 바랍니다. 모르면서 아는 척 하는 그쪽이 답변을 안 하는 것이 도움이 되겠군요. 무슨 반말을 했다는 것인지? 실력이 안되니까 괜한 인신공격이나 하는 한심한 잡류로 보입니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

익명 사용자의 이미지

한글을 잘 읽으세요.
반말이 아니라 반발입니다.
지금 당신이 하고 있는걸 반말이 아니라 반발이라고 합니다.

익명 사용자의 이미지

아이디가 없어서 익명입니다
확언하건데 아이디가 있어도 똑같이 적었을겁니다
남이 시간내서 뭔가 알려주면 따지기전에 자료부터 찾아보세요
댓글에 달린 글자도 제대로 못읽는데 자료 잘찾아볼 것 같지는 않지만 말이죠

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.