C++에서 객체 배열 질문드립니다.

kyma123의 이미지

안녕하세요 C++ 배운지 얼마 안 된 학생입니다.
C++로 간단한 카드 게임을 구현해 보려고 하는데, 카드 정렬 단계에서 모르는 부분이 있어서 질문 드리겠습니다.

일단 제가 짰던 코드를 단순화 해서 올리겠습니다.

#include <algorithm>
#include <iostream>
 
class myclass {
private:
	int a;
	int b;
public:
	// constructor
	myclass(int _a, int _b) : a(_a), b(_b) {}
 
	// copy constructor
	myclass(const myclass& other) : a(other.a), b(other.b) {}
 
	friend std::ostream& operator<<(std::ostream& out, const myclass mc) {
		out << "{" << mc.a << ", " << mc.b << "}";
		return out;
	}
};
 
class sortclass {
private:
	myclass* arr[10];
	int num;
public:
	// constructor
	sortclass() : num(0) {}
 
	void sorting() {
		// 질문드릴 부분!
	}
 
	sortclass& operator+(const myclass& other) {
		arr[num++] = new myclass(other);
		return *this;
	}
 
	friend std::ostream& operator<<(std::ostream& out, const sortclass sc) {
		for(int i = 0; i < sc.num; i++)
			out << *sc.arr[i] << ((i < sc.num-1) ? ", ":"");
		return out;
	}
};

myclass 객체가 a, b라는 두 개의 정수 인수를 갖고 있을 때, myclass 객체 배열을 우선 a에 대해 작은 숫자부터 정렬하고, a가 같은 값일 경우 b에 대해 작은 숫자부터 정렬하는 함수를 작성하고 싶습니다.
예를 들어 main함수가 아래와 같은 경우,

int main() {
	myclass* mc[10];
	sortclass sc;
	int a[10][2] = {{3, 1}, {4, 2}, {2, 5}, {1, 3}, {3, 2}, {3, 5}, {4, 4}, {1, 1}, {2, 2}, {3, 3}};
	for(int i = 0; i < 10; i++) {
		mc[i] = new myclass(a[i][0], a[i][1]);
		sc + *mc[i]; // Input mc[i] into sc.arr[i] (operator+ called)
	}
	cout << sc; // {3, 1}, {4, 2}, {2, 5}, {1, 3}, {3, 2}, {3, 5}, {4, 4}, {1, 1}, {2, 2}, {3, 3}
 
	sc.sorting();
	cout << sc; // {1, 1}, {1, 3}, {2, 2}, {2, 5}, {3, 1}, {3, 2}, {3, 3}, {3, 5}, {4, 2}, {4, 4}
}

위 주석과 같은 식으로 출력이 되게끔 말이죠.
http://stackoverflow.com/questions/12823573/c-sorting-class-array <- 이 문서를 보고 void sortclass::sorting() 함수를 아래와 같이 짜보았습니다.

std::sort(*arr, *(arr + num));

또한 위 링크에 나온 방법대로 myclass 클래스에 operator<을 오버로딩하여 myclass에 아래와 같은 함수를 삽입했습니다.

	bool operator<(const myclass& rhs) {
		if(a == rhs.a)
			// If values of a are same, sort by value of b.
			return (b < rhs.b);
		return (a < rhs.a);
	}

빌드까지는 잘 되는데, 실행을 하면 invalid iterator range 에러가 뜨더군요.
VS의 한 줄 한 줄 읽어가며 컴파일 하는 기능으로 확인해 본 결과, algorithm 헤더파일 내에서 sort의 피벗 값을 구하기 위한 중간과정에서, myclass 클래스끼리의 덧셈/뺄셈 등의 연산이 들어가 이상한 변수들이 피벗값에 들어가는 것 같더군요.
그래서 myclass들끼리의 +-/연산자 등을 오버로딩 해봤는데 아예 호출이 되지 않더군요=_=;;

혹시 제가 너무 조잡하게 했는지, 다른 방법이 있는지, 수정해야 한다면 어디를 수정해야 하는지 설명해주시면 감사하겠습니다.

//ps: 후 그냥 벡터 쓰는 게 낫겠군요. 그래도 클래스 오브젝트를 sort에 직접 넣는 방식으로 해결하는 방법이 혹 없을까 궁금합니다.

mirheekl의 이미지

myclass* mc[10]을 선언하고 내부는 그 밑에서 new myclass()로 동적할당을 합니다.

이 상태로는 sort함수가 각각의 멤버 위치를 정확하게 찾아낼 수가 없습니다. 10개의 오브젝트의 메모리가 모두 동적할당되기 때문입니다.

예를 들어, mc[10]이 각각의 오브젝트용으로 할당받은 주소가 다음과 같다 합시다.

mc[0] = 0x10000;
mc[1] = 0x20000;
mc[2] = 0x15000;
....
mc[9] = 0x05000;

이런식으로 할당이 되었다 치고, sort함수가 처음 주소와 끝 주소인 0x10000과 0x05000을 전달받았다 칩시다. sort함수는 이렇게 주어진 두 개의 주소로 나머지 영역또한 접근합니다. 따라서 이 경우에는 나머지 값들을 읽을 방법이 없는 것입니다. 일반적인 배열, 즉 myclass mc[10]으로 선언하고 sort(&mc[0], &mc[9])로 하면 잘 동작할 겁니다. 각 배열의 멤버들이 연속적인 공간에 존재하기 때문입니다. 해당 배열 자체는 물론 동적으로 생성해도 무방합니다. 아니면 본문대로 그냥 구현을 하되, 소트 함수가 해당 공간에 대해 연속적으로 접근할 수 있게 추가적인 처리를 해주어도 됩니다만, 그럴거면 말씀하신 대로 벡터를 쓰는 게 더 낫겠죠.

마지막으로, 본문 소스에서 sort를 호출할때 사용한 인자도 잘못된 것 같네요. 저렇게 하면 arr이 가진 메모리 범위 이외의 영역을 전달하게 될 듯. 예를 들어 배열 크기가 10일때 arr[0], arr[10]을 전달하게 되겠네요.

--

kyma123의 이미지

정말 감사합니다!

댓글 달기

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