• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

Buffer overrun 관련해서 질문드립니다!

22.10.16 19:45 작성 조회수 275

0

안녕하세요! 항상 양질의 강의와 질문 커뮤니티 덕분에 많이 배우고 있습니다!

강의에 나온 클래스를 직접 구현해봤는데요, 생성자 코드에서 m_data element를 초기화하는 과정에서 buffer overrun이 발생합니다.

IntArray(const initializer_list<int>& list)
		//: IntArray(list.size())
	{
		m_data = new int[list.size()];
		m_length = list.size();
		initialize();
		
		int count = 0;
		for (auto& e : list)
		{
			m_data[count] = e; // buffer overrun 발생
			count++;
		}
	}

그래서 다른 분의 코드를 참고하여 다음과 같이 수정하였습니다.

IntArray(const initializer_list<int>& list)
		: IntArray(list.size())
	{
		/*m_data = new int[list.size()];
		m_length = list.size();
		initialize();*/
		
		int count = 0;
		for (auto& e : list)
		{
			m_data[count] = e; // buffer overrun 발생
			count++;
		}
	}

수정 후 buffer overrun이 사라졌는데 debugger를 돌려도 똑같이 작동하는 거 같아 어디서 잘못됐는지 찾기가 어렵습니다ㅠㅠ

그 이유를 알고싶습니다,,

아래는 전체 코드입니다.

#include <iostream>
#include <initializer_list>

using namespace std;

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

public:
	IntArray(const int& length_in = 0)
		: m_length(length_in)
	{
		m_data = new int[m_length];
		initialize();
	}

	IntArray(const IntArray& arr)
		: IntArray(arr.m_length)
	{}

	IntArray(const initializer_list<int>& list)
		//: IntArray(list.size())
	{
		m_data = new int[list.size()];
		m_length = list.size();
		initialize();
		
		int count = 0;
		for (auto& e : list)
		{
			m_data[count++] = e; // buffer overrun 발생
		}
	}

	~IntArray()
	{
		delete[] m_data;
	}

	void initialize()
	{
		for (int i = 0; i < m_length; i++)
			m_data[i] = 0;
	}

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

	void resize(const int& new_length)
	{
		int* temp = new int[new_length];
		for (int i = 0; i < (new_length < m_length ? new_length : m_length); i++)
			temp[i] = m_data[i];
		delete[] m_data;
		m_length = new_length;
		m_data = temp;
	}

	void insertBefore(const int& value, const int& ix)
	{
		if (ix >= 0 && ix < m_length)
		{
			resize(m_length + 1);
			for (int i = m_length - 1; i > ix; i--)
				m_data[i] = m_data[i - 1];
			m_data[ix] = value;
		}
		else
			cout << "Invalid index" << endl;
	}

	void remove(const int& ix)
	{
		if (ix >= 0 && ix < m_length)
		{
			for (int i = ix; i < m_length - 1; i++)
				m_data[i] = m_data[i + 1];
			resize(m_length - 1);
		}
		else
			cout << "Invalid index." << endl;
	}

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

	IntArray& operator = (const std::initializer_list<int>& list)
	{
		resize(list.size());

		int count = 0;
		for (auto& e : list)
		{
			m_data[count] = e;
			count++;
		}
		return *this;
	}

	IntArray& operator = (const IntArray& arr)
	{
		if (this == &arr)
			return *this;

		delete[] m_data;
		m_length = arr.m_length;

		if (arr.m_data != nullptr)
		{
			m_data = new int[arr.m_length];
			for (int i = 0; i < arr.m_length; i++)
				m_data[i] = arr.m_data[i];
		}
		else
			m_data = nullptr;

		return *this;
	}


	friend ostream& operator << (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 };
	cout << my_arr << endl;
	my_arr.insertBefore(10, 1);
	cout << my_arr << endl;
	my_arr.remove(3);
	cout << my_arr << endl;
	my_arr.push_back(13);
	cout << my_arr << endl;

	// containter : ~가 ~의 member다.

	return 0;
}

 

답변 2

·

답변을 작성해보세요.

1

강민철님의 프로필

강민철

2022.10.17

첨부해주신 코드로는

g++(Ubuntu), visual studio 2017 (Windows), 컴파일로 오류를 재현하기가 어려운 것 같은데,

실행 환경이 어떻게 되시나요?

image

image

혹은 오류 메세지 전체를 첨부해주셔도 좋습니다.

 

0

skf346님의 프로필

skf346

질문자

2022.10.18

안녕하세요!

일단 저는 VS2022 사용하고 있고 얼마전 stackoverflow를 찾아본 결과 vs에서 발생하는 일종의 버그라고 생각됩니다!

https://stackoverflow.com/questions/64713842/any-way-to-avoid-warning-c6386-without-disabling-it-or-code-analysis-altogether

Complier explorer를 통해 gcc 등 컴파일러로 실행해봤는데 warning이 잡히지 않았습니다!

VS code analyzer가 위 코드의 list.size()가 0보다 큰 지 확실하게 판단하기 어려워서 해당 버그가 발생하는것으로 추정됩니다!

이를 max(list.size(), 0)을 사용한 트릭으로 없앨 수는 있다고는 하는데 근본적인 해결책은 정확히 모르겠네요.