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

인프런 커뮤니티 질문&답변

전영대님의 프로필 이미지
전영대

작성한 질문수

홍정모의 따라하며 배우는 C++

10.6 컨테이너 클래스

int array 과제 피드백 부탁드립니다!

작성

·

36

1

#include <initializer_list>
#include <iostream>
#include <memory>

class my_array
{
private:

	int m_length = 0;
	int m_capacity = 0;
	int* m_data = nullptr;

public:
	explicit my_array(int count = 0)
{
	initialize();
}

	my_array(const std::initializer_list<int> &list)
{
	for (const int& ele : list)
	{
		push_back(ele);
	}
}

	~my_array()
{
	reset();
}

	void initialize()
{
	m_data = new int[m_capacity];
}

	void reset()
{
	m_length = 0;
	m_capacity = 0;
	delete[] m_data;
	m_data = nullptr;
}

	void resize(int number = 1)
{
	int* tamp = new int[m_length];
	memcpy(tamp, m_data, m_length * sizeof(int));

	m_capacity += number;

	delete[] m_data;
	m_data = new int[m_capacity];
	memcpy(m_data, tamp, m_length * sizeof(int));

	delete[] tamp;
	tamp = nullptr;
}

	void insert(int idx, int value)
{
	if (m_length == m_capacity)
	{
		resize();
	}
	memmove(m_data + idx + 1, m_data + idx , (m_length-idx) * sizeof(int));
	m_data[idx] = value;
	m_length++;
}

	void remove(int idx)
{
	memmove(m_data + idx, m_data + (idx + 1), (m_length - (idx+1)) * sizeof(int));
	m_length--;
}

	void push_back(const int& value)
{
	if (m_length == m_capacity)
	{
		resize();
	}
	m_data[m_length++] = value;
}


	friend std::ostream& operator << (std::ostream& out, const my_array &arr);

};

 

일단 initailizer_list 사용해여 초기화 할때 push_back 함수로 변형하여 사용했는데 가능한 것인지 궁금합니다.

파괴자에서 reset으로 사용해 보기도 했습니다. 이상입니다 .

답변 2

2

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

 

initialize_list 를 통한 생성자에서 push_back() 을 통해 처리하는 방식도 물론 가능한 방법 중 하나입니다.
다만, push_back() 함수를 호출함으로써 각 요소마다 capacity 검사와 resize() 함수의 호출이 이루어진다는 점에서 효율성이 낮아지게 됩니다.

또한, initialize_list 는 객체의 생성 시점에서 초기 값들을 한 번에 설정하기 위한 목적으로 설계되었음을 고려하여, '멤버 변수들을 직접 초기화' 하는 것이 보다 더 명확한 코드가 될 것 같습니다.

 

위 피드백과 관련하여, 기본 생성자에서 initilize() 함수를 호출하지만 m_capacity0 인 상황이되므로 의미없는 메모리 할당을 수행하게 됩니다. 기본 생성자의 인수가 0 이거나 없는 경우(기본값)에 대해서 추가적인 처리를 해주시면 더 좋을 것 같습니다.

 

메모리 관리는 언제나 중요하므로, 소멸자에서 reset() 함수를 통해서 꼼꼼하게 메모리 누수를 방지한 점은 잘 작성하셨다고 생각됩니다.

 

추가적으로, insert() 함수에서 idx0 보다 작은 경우, 혹은 m_length 보다 큰 경우 등에 대한 예외처리도 고려해보시면 학습에 도움이 되실 것 같습니다.

 

학습에 도움을 드리기 위해서 조심스레 피드백을 드렸지만,
개인적으로 문법 학습 단계에서 이미 훌륭히 잘 구현하신 IntArray 라고 생각하며, 특히 질문자님 스스로 과제를 수행하려하신 노력이 잘 보여지는 코드인 것 같아 더 응원을 해드리고 싶네요.

 

마지막으로, 실제 STL 의 컨테이너들은 '효율성' 을 위해서 capacity 를 "필요할 때 마다, 필요한 만큼", 혹은 1 씩 증가시키지 않고, 어느정도 여유롭게 메모리를 할당하여 효율성을 향상시킨다는 점도 안내드려봅니다.

 

잘 구현하셨습니다!

 

IntArray 구현 과제와 관련된 다른 수강생 분들의 질문&답변 사례도 첨부드리오니, 비교해보시면서 학습에 도움이 되시길 바래봅니다.

0

안녕하세요, 인프런 AI 인턴입니다. 전영대님께서 작성해 주신 my_array 클래스 코드를 잘 살펴보았습니다. 몇 가지 피드백과 함께 코드를 어떻게 개선할 수 있을지 안내드릴게요.

피드백 및 개선 사항

  1. initializer_list로 초기화:
    initializer_list를 사용하여 배열을 초기화하고 push_back을 통해 요소를 추가하는 구조는 가능합니다. 다만 주의할 점은 resize가 호출될 때마다 배열의 재할당이 자주 발생할 수 있어 성능에 영향을 줄 수 있고, 이를 해결하기 위해 초기 m_capacitylist.size()로 설정하여 필요한 만큼 할당하는 것이 좋습니다.

  2. 디폴트 매개변수 활용 주의: resize(int number = 1)number만큼 용량을 늘리는 역할을 하는데, number가 현재 용량보다 작게 설정될 수 있는 경우를 조심해야 합니다. 또, 주의해야 할 점은 resize 함수는 m_capacity 대신 m_capacity + number 를 통해 용량을 늘려야 한다는 것입니다.

  3. 메모리 관리:

    • initialize 함수에서 초기 용량을 정해놓지 않았기 때문에 push_back 호출 시 매번 용량을 +1씩 증가시키고 있습니다. std::vector처럼 초기 용량을 따라서 줄 수 있는 구조가 되면 성능을 더 향상시킬 수 있습니다.
    • 파괴자에서는 reset() 함수를 호출하여 메모리를 정리해주는 방식은 좋습니다. 이로써 중복된 메모리 해제를 방지할 수 있습니다.
  4. 그 외:

    • resize 함수의 맨 앞에서 나타난 int* tamp = new int[m_length]; 부분에서 m_length 대신 현재의 m_capacitym_capacity + number 전후의 적절한 값 설정을 사용해보세요.
    • 메서드들이 모두 공개되어 있어서 필요하지 않은 경우 private으로 선언하고 꼭 필요한 경우만 public으로 노출하도록 조정하면 안전성이 높아질 수 있습니다.

관련 질문 링크

다양한 C++ 컨테이너 관련 구현에 대한 질문이 있어 아래 링크를 참고하시면 도움이 될 수 있습니다:

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

전영대님의 프로필 이미지
전영대

작성한 질문수

질문하기