원형리스트 덧셈하는건데요..

widgie의 이미지

우선 숙제임을 밝혀둡니다 -_-;;

하다하다 도저히 막혀서 이렇게 올리네요

코드는 아래와 같습니다.

다항식 2개를 입력받아

연산자 오버로딩으로

두 다항식의 합을 출력하는건데

vc6 에서 컴파일 했을 경우

두 다항식의 입력과 출력은 되는데

그 합을 출력하는 부분에서 멈춰버립니다.

며칠밤을 고민했는데도 도대체 뭐가 문제인지

감이 안 잡힙니다. 도움 좀 주세요 :oops:

#include <iostream.h>

struct Term {
	int exp;
	int coef;
	void Init(int c, int e){coef = c; exp = e;};
};

class List;
class CircListIterator;

class ListNode {
	friend class List;
	friend class CircListIterator;
	public:
		ListNode(Term k) {
			data = k;
			link = 0;
		};
	private:
		Term data;
		ListNode *link;
};

class List {
	friend class CircListIterator;
	public:
		void Attach(Term k);
		List() {
			first = 0;
			last = 0;
		};
		~List();
	private:
		ListNode *first;
		ListNode *last;
		ListNode *head;
};

List::~List() {
	ListNode* next;
	ListNode* now;
	now = head;
	next = head;
	while(true){
		next = next->link;
		delete now;
		if(next == NULL) break;
		now = next;
	}
}

void List::Attach(Term k){
	ListNode *newnode = new ListNode(k);
	if(first==0){
		Term a;
		a.Init(0,-1);
		ListNode *node = new ListNode(a);
		first = newnode;
		last = newnode;
		head = node;
		head->link = first;
		newnode->link = head;
	} else {
		last->link = newnode;
		newnode->link = head;
		last = newnode;
	}
}

class CircListIterator {
	public:
		CircListIterator(const List& l):list(l), current(l.first){};
		bool NotNull() {
			if(current) return true;
			else return false;
		};
		bool NextNotNull() {
			if(current && current->link) return true;
			else return false;
		};
		Term* First() {
			if(list.first) return &list.first->data;
			else return 0;
		}
		Term* Next() {
			current = current->link;
			return &current->data;
		};
	private:
		const List& list;
		ListNode* current;
};

class Polynomial{
	private:
		List poly;
	public:
		Polynomial(){};
		Polynomial(const Polynomial &);
		friend Polynomial operator+(const Polynomial&, const Polynomial&);
		friend istream& operator>>(istream&, Polynomial&);
		friend ostream& operator<<(ostream &, const Polynomial &);
};

Polynomial::Polynomial(const Polynomial &a){
	Term *p, *q, temp;
	CircListIterator iter(poly);
	CircListIterator iter2(a.poly); 
	p = iter.First();
	q = iter2.First();
	while (iter.NotNull()) {
		temp.Init(0,-1);
		poly.Attach(temp);
		p = iter.Next();
	}
	while (iter2.NotNull()) {
		temp.Init(q->coef,q->exp); 
		poly.Attach(temp);
		q = iter2.Next();
	}
}

char compare(int x, int y) {
	if(x == y) return '=';
	else if(x < y) return '<';
	else return '>';
}

Polynomial operator+(const Polynomial& a, const Polynomial& b){
	Term *p, *q, temp;
	CircListIterator Aiter(a.poly);
	CircListIterator Biter(b.poly);
	Polynomial c;
	p = Aiter.First();q = Biter.First();
	while(1)
		switch( compare(p->exp, q->exp) ) {
			case '=':
				if( p->exp == -1 ) return c;
				else {
					int sum = p->coef + q->coef;
					if(sum) {
						temp.Init(sum, q->exp);
						c.poly.Attach(temp);
					}
					p = Aiter.Next();
					q = Biter.Next();
				}
				break;
			case '<':
				temp.Init(q->coef, q->exp);
				c.poly.Attach(temp);
				q = Biter.Next();
				break;
			case '>':
				temp.Init(p->coef, p->exp);
				c.poly.Attach(temp);
				p = Aiter.Next();
				break;
		}
}

istream& operator>>(istream& is, Polynomial& p){
	Term temp;
	int exp;
	int coef;
	char ch = ' ';
	while( ch != '\n')	{
		is >> coef >> exp;
		temp.Init(coef, exp);
		p.poly.Attach(temp);
		ch = is.get();
	}
	return is;
}

ostream& operator<<(ostream & os ,const Polynomial & a) {
	Term *p;
	CircListIterator iter(a.poly); 
	p = iter.First();
	while(!((p->exp) == -1)){
		if( p->coef > 0 && p!=iter.First() ) cout << " + ";
		cout << p->coef << "x^" << p->exp ; 
		p = iter.Next();
	}
		
	cout << endl;
	return os;
}

int main() {
	Polynomial A,B,C;

	cout <<"입력 예제 :  3x^14 + 2x^8 - 7x^3 + 1  ->  3 14 2 8 7 3 1 0 "<<endl;

	cout <<"\n A 다항식 : ";
	cin >> A;
	
	cout <<"\n B 다항식 : ";
	cin >> B;

	cout<<endl;

	cout<<"A = "<<A<<endl;
	cout<<"B = "<<B<<endl;

	C = A + B;

	cout<<"C = "<<C<<endl;

	return 0;
}
pool007의 이미지

C = A + B;

여기서 A+B의 결과는

Polynomial operator+(const Polynomial& a, const Polynomial& b)

에서 계산됩니다.

그리고 opeartor+ 안에서는

if( p->exp == -1 ) return c;

로 리턴합니다.

그러면 말이죠...

C = A + B 에서 이번엔 operator= 가 호출될 차례입니다.
그런데, Polynomial내의 List에는 operator=가 정의되지 않았습니다.

따라서! bitwise로 그냥 내용을 복사합니다.
(비트 단위로 그냥 복사되므로, 같은 내용을 가리키는 포인터가 2개)

그런데 return c에서 c는 지역변수이므로 그 내용이 파괴됩니다.
그러면서 그 멤버인 List의 소멸자를 호출하고, 따라서 리스트는
파괴됩니다.

결국 복사한 것은 쓸모가 없게 된거죠...

다시 말해서

c.List -> 0x1
반환값 -> 0x1

이라는 같은 주소를 가리키다가

c.List-> null
반환값-> 0x1 (c가 소멸하면서 이 주소내의 list는 이미 파괴됨.)

해결책은, 동적으로 할당하는 메모리에서는 언제나 복사 생성자와 operator=를 같이 정의하라는 것입니다.

--
Passion is like genius; a miracle.

댓글 달기

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