인프런 커뮤니티 질문&답변
버퍼 오버런 관련 질문 합니다.
작성
·
1.8K
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
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 이 링크에서도 "포인터 문법을 사용해 동적할당을 하는 경우에 잘 발생합니다." 라고 언급해주시고 있네요!
(전체 코드 추가해주신 배려 감사드립니다.☺)






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