inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

9.12 이니셜라이져 리스트 initializer list

버퍼 오버런 관련 질문 합니다.

1810

홍재윤

작성한 질문수 3

0

강의에서는 생성자에서 다른 생성자를 호출하는식으로 코드를 작성하였습니다.

그런데, 호출되는 생성자의 코드를 똑같이 적어주는 방식으로하면 컴파일러가 버퍼오버런 경고를 띄어줍니다

그래서 std::vector, std::array, initializer_list, 정적배열 로 실험을 해보았는데,

벡터와 이니셜라이저리스트에서는 똑같은 경고를 띄어주더라구요..

이런 경고를 띄어주는 이유와, 해결 방법에 대해 질문합니다. 

vs2019 , 디버그모드입니다.감사합니다

아래 코드를 첨부합니다. 코드를 긁어서 복사하시면

더 편하게 질문을 이해하실 수 있습니다.

//강의에서 사용된 코드

#include <initializer_list>

#include <vector>

#include <array>

class My_array

{

private:

unsigned m_length = 0;

int* m_ptr = nullptr;

public:

My_array()

{}

My_array(const unsigned& length)

{

m_length = length;

m_ptr = new int[m_length];

}

My_array(const std::initializer_list<int>& list)

//:My_array(list.size())

{ //생성자를 호출하지않고 생성자와 똑같은 코드를 적어줌

m_length = list.size();

m_ptr = new int[m_length];

unsigned i = 0;

for (const auto& e : list)

{

m_ptr[i] = e;

++i;

}

}

};

//여기서부터 실험 코드

void print(int* ptr);

int main()

{

//동적 할당을 받은후 정적배열의 데이터들을 복사

int arr[]{ 1,2,3,4,5 };

const int length_arr = sizeof(arr) / sizeof(arr[0]);

int* ptr_arr = new int[length_arr];

unsigned i = 0;

for (const auto& e : arr)

{

ptr_arr[i] = e;

++i;

}

print(ptr_arr);

//동적할당을 받은후 std::array의 데이터들을 복사

std::array<int, 5> stdArr {1, 2, 3, 4, 5, };

int* ptr_stdArr = new int[stdArr.size()];

i = 0;

for (const auto& e : stdArr)

{

ptr_stdArr[i] = e;

++i;

}

print(ptr_stdArr);

//동적할당을 받은후 initializer list의 데이터들을 복사

auto list={ 1,2,3,4,5 };

int* ptr_list = new int[list.size()];

i = 0;

for (const auto& e : list)

{

ptr_list[i] = e;

++i;

}

print(ptr_list);

//동적 할당을 받은후 벡터의 데이터들을 복사

std::vector<int> my_vec{ 1,2,3,4,5 };

int* ptr_vec = new int[my_vec.size()];

i = 0;

for (const auto& e : my_vec)

{

ptr_vec[i] = e;

++i;

}

print(ptr_vec);

return 0;

}

void print(int* ptr)

{

for (unsigned i = 0; i < 5 ;++i)

{

cout << ptr[i] << "  ";

}

cout << endl;

}

4:40 C++

답변 1

1

안소

	int* ptr_list = new int[list.size()];
	i = 0;
	for (const auto& e : list)
	{
		ptr_list[i] = e;
		++i;
	}

버퍼 오버펀 경고가 발생하는 이유는 std::vector, std::array, initializer_list, 정적배열 인 것과는 관련이 없고 ptr_list[i] 때문입니다. 

ptr_list 는 동적할당 받은 메모리를 가리키는 포인터입니다. ptr_list 을 사용하여 [인덱스] 나 산술연산을 사용하여 실제 동적할당 받은 메모리의 영역을 얼마든지 벗어날 수 있다는 그런 우려가 있습니다. 위 코드에서 i 가 ptr_list 가 가리키는 메모리를 벗어나지 않는 선까지만 증가해야한다는 그러한 안전장치가 될만한 전제는 없습니다. 저 코드에서 원소를 차례로 내뱉는 list 의 크기에만 의존할 뿐이죠.

그래서 포인터로 '동적할당' 메모리를 [] 연산자를 통해 인덱스로 참고할 땐 저런 경고를 띄어주는 듯 합니다. 말그대로 경고일 뿐이라 정말 그 경고메세지대로 실제로 동적 할당 메모리를 벗어난 공간을  ptr_list 가 참조하게 되는 것 아닌 이상 실행에는 아무 문제 없습니다. 컴파일러가 체크해줄 수 없으니 범위를 벗어난 곳을 참조하지 않도록 조심하세요~ 로 받아들이고 넘어가면 되는 경고라고 생각해주시면 될 것 같아요! https://pang2h.tistory.com/410 이 링크에서도 "포인터 문법을 사용해 동적할당을 하는 경우에 잘 발생합니다." 라고 언급해주시고 있네요!

(전체 코드 추가해주신 배려 감사드립니다.☺)

0

홍재윤

큰도움이 되었습니다. 답변해 주셔서 감사합니다.

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

1

481

1

메모리 주소 10진수로 출력

1

672

1

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

1

514

1

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

1

548

1

메모리 주소에 관한 질분

0

687

1

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

0

558

1

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

0

448

1

Digit 뒤에 reference를 사용하는 이유

0

512

1

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

0

325

1

dat파일이...

0

540

1

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

0

651

1

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

0

455

1

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

1

392

1

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

0

565

1

마지막 예제 질문

0

305

1

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

0

382

1

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

1

415

1

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

0

313

1

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

0

448

1

3분 17초 질문

0

354

1

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

0

450

1

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

0

453

2

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

0

304

1

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

1

495

1