인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

Inflearn Community Q&A

yoodud's profile image
yoodud

asked

C++ by Hong Jeong-mo

10.6 Container Classes

IntArray 숙제 올립니다.(수정해야 할 부분 알려주시면 감사합니다.)

Written on

·

111

·

Edited

1

#include <iostream>
#include <vector>
#include <array>
#include <cstdarg>
#include <cassert>
#include <initializer_list>

using namespace std;
// 컨테이너 클래스(Container Classes)

class IntArray
{
private:
	int m_capacity = 0;
	int m_length = 0;
	int* m_data = nullptr;

public:
	//Constructors
	IntArray(std::initializer_list<int> values)
	{
		std::cout << "IntArray::IntArray " << std::endl;

		assert(values.size() >= 0);

		m_length = values.size();
		m_capacity = m_length * 2;
		m_data = new int[m_capacity];

		int ix = 0;
		for (auto value : values)
		{
			m_data[ix] = value;
			std::cout << m_data[ix] << ", ";
			++ix;
		}
		std::cout << std::endl;
	}

	~IntArray()
	{
		if (m_data != nullptr)
			reset();
	}


	void reset()
	{
		delete[] m_data;
		m_data = nullptr;

		m_length = 0;
		m_capacity = 0;
	}

	void resize(const int& size)
	{
		assert(size >= 0);	// size가 0보다 작거나 같을때 에러 발생

		// 만약 m_data == nullptr 이면 새로 메모리를 잡음
		if (m_data == nullptr)
		{
			m_length = size;
m_capacity = m_length * 2;
m_data = new int[m_capacity];
		}

		// 만약 현재 m_capacity보다 m_length가 크다면 다시 용량 재할당 해준다.
		if (m_length >= m_capacity)
		{
			m_capacity *= 2;
			int* temp = new int[m_capacity];

			for (int i = 0; i < m_length; ++i)
				temp[i] = m_data[i];

			delete[] m_data;

			m_data = temp;
		}

		// 기존 사이즈보다 작은건 상관이 없다 인덱스 접근을 못하게 되니깐
	}

	void insertBefore(const int& value, const int& ix)
	{
		assert(ix > 0);

		++m_length;
		int index = m_length - 1;

		// 사이즈가 용량을 넘으면 다시 할당
		if (m_length >= m_capacity) resize(m_length);

		for (int i = index; i <= index; --i)
		{
			if (ix == i) break;
			int curr = m_data[i];
			int before = m_data[i - 1];
			m_data[i] = m_data[i - 1];
		}

		m_data[ix] = value;
	}

	void push_back(const int& value)
	{
		++m_length;

		if (m_length >= m_capacity) resize(m_length);

		m_data[m_length - 1] = value;
	}

	friend std::ostream& operator<<(std::ostream& out, const IntArray& data)
	{
		for (int i = 0; i < data.m_length; ++i)
		{
			if (i != 0) out << ", ";
			out << data.m_data[i];
		}
		return out;
	}

	void remove(const int& ix)
	{
		assert(ix >= 0);

		int tempIx = m_length;
		--m_length;

		for (int i = ix; i <= m_length; ++i)
		{
			m_data[i] = m_data[i + 1];
		}
	}
};

int main()
{
	IntArray my_arr{ 1,2,3,4,5 };
	
	my_arr.push_back(100);
	cout << my_arr << endl;
	my_arr.push_back(200);
	cout << my_arr << endl;
	my_arr.push_back(300);
	cout << my_arr << endl;
	my_arr.push_back(400);
	cout << my_arr << endl;
	my_arr.insertBefore(50, 3);
	cout << my_arr << endl;

	my_arr.push_back(600);
	my_arr.push_back(700);
	my_arr.push_back(800);
	my_arr.push_back(900);
	my_arr.push_back(1000);
	cout << my_arr << endl;

	my_arr.remove(5);
	cout << my_arr << endl;
	return 0;
}
c++

Answer 2

1

안녕하세요? 질문&답변 도우미 Soobak 입니다.

 

꼼꼼하게 코드를 살펴보며 조언을 드려봅니다.

전반적으로 잘 구현하신 것 같습니다.
특히, 교수님께서 강의 중 안내해주신 내용을 바탕으로 스스로 노력하시며 구현해내신 과정이 잘 느껴지는 코드네요.

다만, 그 과정에 있어서 구현하신 내용 중 일부 불필요한 부분이 남아있는 것 같습니다.

예를 들어, insertBefore() 함수의 for 반복문 중, int curr 변수와 int before 변수는 사용되지 않으며, remove() 함수의 int tempIx 변수 역시 사용되지 않습니다.

image.png

 

그리고, 생성자의 assert(values.size() >=0); 부분은 언제나 참이 됩니다.

image.png

(위의 사진은 조금 더 엄밀하게 조언을 드리고자, 컴파일러의 옵션을 조정하여 경고 수준의 경우에도 오류로 취급하도록 한 것입니다. 표기된 error 는 모두 warning 입니다.)

 

또한, insertBefore() 함수의 for 반복문에서 조건으로 for (int i = index; i <= index; --i) 을 사용하셨는데, 이 부분 또한 논리 상 iindex 보다 커지는 경우는 없습니다.
한 번, 위의 assert(ix > 0) 단언과 반복문 내의 if(ix == i) break; 조건문을 함께 고려해보시면서 코드의 가독성을 조금 더 높이시는 방향으로 수정하시면 보다 좋은 코드가 될 것 같습니다.

 

마지막으로, 강의 2:05 부분에서 교수님께서 안내해주신 initialize() 함수 또한 한 번 구현 후 생성자에서 활용해보시면 좋을 것 같습니다.

 

image.png

기능과 메모리 누수 검사도 꼼꼼히 해보았으며, 큰 문제가 없습니다.

개인적으로, 노력하신 과정이 잘 느껴져서 제가 보다 더 정성을 담아 답변을 드리게 되는 코드이네요.
답변을 드리기 위해 굳이 꼼꼼히 조언을 드렸으나, 문법 학습 단계에서 배열 자료구조와 메모리 할당/해제 에 대한 이해, 그리고 구현 능력은 충분하신 것으로 생각됩니다.
추후 자료구조와 알고리듬 학습을 본격적으로 진행하실 때, 넓은 시야로 보다 더 많은 부분을 학습하실 수 있는 밑바탕이 되실 것 같습니다. 잘 구현하셨습니다.

yoodud님의 프로필 이미지
yoodud
Questioner

안녕하세요~ Soobak님,

제가 만든 코드를 세세하게 확인해 주시고 문제 되는 부분과 불필요한 요소들을

알려주셔서 감사합니다~ 😄

알려주신 내용을 바탕으로 다시 한번 리팩토링 해보고 더 생각해 봐야겠네요.

왠지 질문을 올리면 Soobak님 답글을 기다리게 되네요!
더 열심히 하게됩니다 ㅎㅎ 😄

0

안녕하세요, 인프런 AI 인턴입니다. yoodud님, 질문 주셔서 감사합니다. 코드를 검토한 결과 몇 가지 수정 및 개선이 필요한 부분이 있습니다. 아래에 요약해드리겠습니다.

  1. 메모리 관리: 현재 resize 함수에서 초기화되지 않은 배열의 경우 따로 메모리를 할당 하지만, 이 부분이 코드 흐름과 맞지 않을 수 있습니다. resize 함수는 이미 초기화 된 배열을 재할당하는 용도로 사용하는 것이 일반적입니다. 초기화는 생성자 내에서 수행되어야 합니다.

  2. insertBefore 함수:

    • assert(ix > 0);: 인덱스가 0 포함하여 유효해야 하므로 ix >= 0으로 변경하는 것이 좋습니다.
    • for loop에서 잘못된 범위 선언으로 인해 잘못된 동작을 유발할 수 있습니다. 인덱스를 이동시킬 때 범위를 제대로 설정하세요. 종료 조건을 ix > 0 && i >= ix로 수정해보세요.
  3. resize 함수:

    • resize 함수가 사용될 때 현재 용량과 목표 용량을 비교하여 용량이 모자랄 때만 재할당을 수행하도록 하는 부분이 더 필요합니다.
    • 사이즈가 증가하거나 감소하는 경우를 코드에서 명확히 해주면 좋습니다.
  4. remove 함수:

    • 루프 조건에서 엘리먼트의 삭제 처리 후 인덱스 재배치를 더 명확히 처리하여 베이스 케이스를 다뤄야 합니다.
  5. 데이터 초기화 문제:

    • delete[]와 같은 메모리 해제는 할당이 완료된 후에 이루어져야 하며, 데이터를 구분하는 기준이 명확해야 합니다.

이와 관련하여 기초 자료구조와 C++에서의 배열 관리 내용을 참조하여 기본적인 구조 설계를 하고, resize에 대한 더 나은 관리 방법도 포함하는 것이 좋습니다.

[관련 질문 URL](https://www.inflearn.com/questions/13740)

위와 같은 부분만 개선하셔도 현재 구현하신 목록 관리 객체가 더 안정적으로 작동할 것입니다. 추가로 고민되시거나 이해가 안 가시는 부분이 있으시면, 댓글로 질문해 주세요. 도움이 되신다면 좋겠습니다!

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

yoodud's profile image
yoodud

asked

Ask a question