작성
·
20
1
안녕하세요 10.6 컨테이너 클래스 강의에 IntArray 구현해보았는데 피드백 요청드립니다.
잘못된 곳이라던가 좀 더 공부가 필요한 부분 지적해주시면 너무 감사드립니다.
#include <iostream>
#include <initializer_list>
class IntArray
{
private:
int m_length = 0;
int* m_data = nullptr;
public:
IntArray(const std::initializer_list<int> number)
{
m_length = number.size();
m_data = new int[m_length];
int count = 0;
for (auto& arr : number)
{
if (count < m_length)
{
m_data[count] = arr;
++count;
}
}
}
IntArray(const IntArray& copy)
{
m_length = copy.m_length;
m_data = new int[m_length];
for (int i = 0; i < m_length; i++)
m_data[i] = copy.m_data[i];
std::cout << "복사 생성자 호출" << std::endl;
}
~IntArray()
{
delete[] m_data;
std::cout << "메모리 해제" << std::endl;
}
void reset()
{
if (m_data != nullptr)
{
m_length = 0;
delete[] m_data;
m_data = nullptr;
}
}
void resize(const int& size)
{
int* temp_data = new int[size];
for (int i = 0; i < size; i++)
{
temp_data[i] = m_data[i];
if (i >= m_length)
{
temp_data[i] = 0;
}
}
delete[] m_data;
m_length = size;
m_data = temp_data;
}
void insertBefore(const int& insert, const int& before)
{
if (before < 0 || before > m_length)
{
std::cout << "배열의 크기 확인" << std::endl;
return;
}
int* temp_data = new int[m_length + 1];
for (int i = 0, j = 0; i < m_length + 1; i++)
{
if (i == before)
{
temp_data[i] = insert;
}
else
{
temp_data[i] = m_data[j++];
}
}
delete[] m_data;
m_data = temp_data;
m_length++;
}
void remove(const int& number)
{
if (number < 0 || number > m_length)
{
std::cout << "배열의 크기 확인" << std::endl;
return;
}
int* temp_data = new int[m_length - 1];
for (int i = 0, j = 0; i < m_length; i++)
{
if (i != number)
temp_data[j++] = m_data[i];
}
delete[] m_data;
m_data = temp_data;
m_length--;
}
void push_back(const int& number)
{
int* temp_data = new int[m_length + 1];
for (int i = 0; i < m_length; i++)
temp_data[i] = m_data[i];
temp_data[m_length] = number;
delete[] m_data;
m_data = temp_data;
m_length++;
}
friend std::ostream& operator << (std::ostream& out, const IntArray& arr)
{
for (int i = 0; i < arr.m_length; i++)
{
out << arr.m_data[i] << " ";
}
return out;
}
};
int main()
{
IntArray my_arr{ 1, 3, 5, 7, 9 };
my_arr.insertBefore(10, 1);
std::cout << my_arr << std::endl;
my_arr.remove(3);
std::cout << my_arr << std::endl;
my_arr.push_back(13);
std::cout << my_arr << std::endl;
}
답변 2
1
안녕하세요? 질문&답변 도우미 Soobak 입니다.
메모리 접근과 관련된 일부 부분을 제외하고, 전반적으로 잘 구현하셨습니다. 👍
꼼꼼히 살펴보고 피드백 드려봅니다.
void resize(const int& size)
{
int* temp_data = new int[size];
for (int i = 0; i < size; i++)
{
temp_data[i] = m_data[i];
if (i >= m_length)
{
temp_data[i] = 0;
}
}
delete[] m_data;
m_length = size;
m_data = temp_data;
}
: resize()
함수의 구현에 있어서 기존의 크기보다 새롭게 할당하는 크기가 큰 경우, 읽지 말아야 할 메모리에 접근하게 됩니다. 즉, i >= m_length
일 때에도 m_data[i]
에 접근하므로 정의되지 않은 동작이 발생하게 됩니다.
또한,
void insertBefore(const int& insert, const int& before)
{
if (before < 0 || before > m_length)
{
std::cout << "배열의 크기 확인" << std::endl;
return;
}
int* temp_data = new int[m_length + 1];
for (int i = 0, j = 0; i < m_length + 1; i++)
{
if (i == before)
{
temp_data[i] = insert;
}
else
{
temp_data[i] = m_data[j++];
}
}
delete[] m_data;
m_data = temp_data;
m_length++;
}
: 여기에서 temp_data[i] = m_data[j++]
으로 j
값을 매번 증가시키는 경우, 반복문이 끝나기전 j
가 m_length
의 범위를 초과하여 잘못된 메모리에 접근할 수 있습니다.
예를 들어,
int main()
{
IntArray my_arr{ 1, 3, 5, 7, 9 };
my_arr.insertBefore(10, 1);
std::cout << my_arr << std::endl;
my_arr.resize(10);
std::cout << my_arr << std::endl;
my_arr.push_back(13);
std::cout << my_arr << std::endl;
}
질문자님의 코드에서 main()
함수를 위와 같이 바꾸어 메모리 검사를 진행해보면, resize()
함수와 insertBefore()
함수에서 잘못된 메모리 접근이 발생합니다.
만약, 제가 질문자님의 코드를 수정해본다면 resize()
함수의 반복문 안의 부분을
if (i < m_length)
temp_data[i] = m_data[i];
else
temp_data[i] = 0; // 초기화
과 같이 변경한 후, insertBefore()
함수에서 수정된resize()
함수를 활용하여 배열의 크기를 조정할 것 같습니다.
위 내용 이외에는 문제 없이 잘 구현하셨습니다.
의욕적으로 학습하시는 점 진심으로 응원드리며, 잘 학습하고 계시는 것 같아 한번 더 응원드립니다! 😁
아래는 문제가 있거나 부족한 부분이 아닌, 코드를 살펴보면서 추가적으로 개선해보셔도 좋을 것 같은 부분에 대한 피드백입니다.
IntArray(const std::initializer_list<int> number)
{
m_length = number.size();
m_data = new int[m_length];
int count = 0;
for (auto& arr : number)
{
if (count < m_length)
{
m_data[count] = arr;
++count;
}
}
}
: 이 부분에서 if (count < m_length)
조건문은 불필요한 부분 같습니다. for()
문 내부에서 m_length
만큼 반복하기 때문에 count
가 m_length
보다 커지는 경우가 없습니다.
IntArray(const IntArray& copy)
{
m_length = copy.m_length;
if (m_length > 0)
{
m_data = new int[m_length];
for (int i = 0; i < m_length; i++)
m_data[i] = copy.m_data[i];
}
else
{
m_data = nullptr;
}
std::cout << "복사 생성자 호출" << std::endl;
}
: 복사 생성자의 경우 복사 대상 배열이 비어있는 경우, 즉, m_length == 0
인 대상 배열의 경우에 대해서 명시적으로 처리하면 더 안전한 코드가 됩니다.
잘 작성하셨습니다!
IntArray
구현 과제와 관련된 다른 수강생 분들의 질문&답변 사례도 첨부드리오니, 비교해보시면서 학습에 도움이 되시길 바래봅니다.
0
안녕하세요, 인프런 AI 인턴입니다. jjk0806님
IntArray 클래스 구현에 대해 피드백을 요청하셨군요. 여러 가지 작업을 잘 수행하기 위한 기능이 포함되어 있는 것 같습니다. 몇 가지 중요한 점과 개선 사항을 짚어드리겠습니다.
reset
함수는 배열을 초기 상태로 되돌리기 위해 사용됩니다.resize
, insertBefore
, remove
함수 모두에서 범위를 벗어난 접근에 대한 예외 처리를 더 강화할 필요가 있습니다. 이러한 처리가 있어야 프로그램이 예기치 않은 입력으로부터 더욱 안전한 동작을 할 수 있습니다.resize
함수에서는 기존 데이터의 범위를 넘어서는 경우 새 메모리 공간을 0으로 초기화 하고 있습니다. 그러나 복사할 데이터가 그보다 적을 경우 사용되지 않는 메모리는 초기화되지 않기 때문에 이 부분에 대해서도 고려할 필요가 있습니다.위 내용에 관해 추가로 궁금한 부분이 있다면, 자유롭게 질문 주세요. 다음은 비슷한 질문과 답변 링크를 참조하셔서 더 많은 정보를 얻으실 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.