inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Học C++ cùng Hong Jeong-mo

10.6 Các lớp chứa

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

Đã giải quyết

517

skf346

2 câu hỏi đã được viết

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;
}

 

C++

Câu trả lời 2

1

kangminchul

첨부해주신 코드로는

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

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

image

image

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

 

0

skf346

안녕하세요!

일단 저는 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)을 사용한 트릭으로 없앨 수는 있다고는 하는데 근본적인 해결책은 정확히 모르겠네요.

변수가 메모리에 저장되는 것을 알려주는 강의가 어떤강의였죠

1

466

1

메모리 주소 10진수로 출력

1

653

1

클래스 템플릿 특수화에서 boolalpha로 표현된 리턴값에 대해 질문이 있습니다.

1

499

1

여러가지 리턴 타입에 관한 강의가 어떤 걸까요?

1

534

1

메모리 주소에 관한 질분

0

679

1

인터페이스 클래스에서 reportError의 매개변수에 대해 궁금한 것이 있습니다.

0

549

1

형변환 오버로딩에서 const 관련 질문이 있습니다.

0

443

1

Digit 뒤에 reference를 사용하는 이유

0

510

1

4.2 전역 변수, 정적 변수, 내부 연결, 외부 연결

0

323

1

dat파일이...

0

539

1

TODO:대입 연산자 오버로딩에 대한 소스코드입니다.

0

644

1

복사 생성자 관련 질문이 있습니다.

0

454

1

수업 중 궁금한점이 있습니다.

1

390

1

라이브러리자체가 이해가 되지 않습니다.

0

561

1

마지막 예제 질문

0

302

1

증감연산자 위치에 따른 수행 순서 질문입니다.

0

375

1

단항 연산자 오버로딩에서 return 부분에 질문이 있습니다.

1

411

1

friend함수 관련 질문이 있습니다.

0

312

1

operator+ 정의부분에서 궁금한 것이 있습니다.

0

447

1

3분 17초 질문

0

350

1

함수에 값을 대입한다는 개념이 이해가 되지 않습니다.

0

448

1

int getvalue() const에서 const는 왜 뒤에 붙는건가요?

0

445

2

const Something &st에서 const를 빼면 안되나요?

0

300

1

friend함수는 다른 클래스의 멤버함수로 쓸 수 없나요??

1

493

1