• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

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

21.07.23 12:01 작성 조회수 1.33k

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;

}

답변 1

답변을 작성해보세요.

1

안소님의 프로필

안소

2021.07.24

	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 이 링크에서도 "포인터 문법을 사용해 동적할당을 하는 경우에 잘 발생합니다." 라고 언급해주시고 있네요!

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

홍재윤님의 프로필

홍재윤

질문자

2021.07.24

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