연습문제 질문있습니다.
IntArray& operator = (const std::initializer_list<int>& list)
{
cout << "Assignment operator " << endl;
delete[] m_data;
m_length = list.size();
m_data = new int[m_length];
int count = 0;
for (auto& element : list)
{
m_data[count] = element;
++count;
}
return *this;
}연습문제로 이렇게 짜봤는데 m_data[count] = element; 부분에서 buffer overrun이 발생한다고 나옵니다. 그런데 IntArray(const std::initializer_list<int>& list)를 만들 때도 똑같은 코드가 쓰였는데 이때는 왜 에러메시지가 발생하지 않았는지 궁금합니다.
답변 1
0
혹시 전체 소스 코드를 첨부해주실 수 있을까요?
0
// 기본 자료형으로 array를 만들 때는 initializer_list를 이용해서 값을 편하게 초기화할 수가 있었다.
// 이번에는 class 같은 사용자 정의 자료형에서 생성자나 대입 연산자를 만들 때 편하게 사용할 수 있는 std::initilalizer_list 사용법에 대해서 알아본다.
#include <iostream>
#include <cassert>
#include <initializer_list>
using namespace std;
class IntArray
{
private:
unsigned m_length = 0;
int* m_data = nullptr;
public:
IntArray(unsigned length)
: m_length(length)
{
m_data = new int[length];
}
IntArray(const std::initializer_list<int>& list)
: IntArray(list.size())
// 다른 생성자를 호출해서 메모리를 받아오고 있다. IntArray(unsigned length) 생성자에서 메모리를 받아주고 있다.
{
int count = 0;
for (auto& element : list)
{
m_data[count] = element;
++count;
//m_data[count++] = element;
// C 스타일에 익숙한 사람들은 안에 넣어버리기도 한다.
// 요즘에는 컴파일러도 빨라지고 컴퓨터도 빨라지고 그래서 교수같은 경우는 사람이 실수하지 않도록 분리하는 편이다.
}
//for (unsigned count = 0; count < list.size(); ++count)
// m_data[count] = list[count]; // error
// count가 따로 되어있으니깐 번거로워보여서 옛날 프로그래머들은 이렇게 시도할 수 있다.overrun
// 그런데 std::initializer_list는 대괄호 operator를 제공하지 않는다. std::array나 std::vector에서는 사용할 수 있었는데 std::initializer_list는 제공해주지 않는다.
}
// 그래서 내부적으로 구현이되어있을 때 std::initializer_list 같은 경우는 iterator라는 것을 사용해서 for문을 돌리게 되어있는데
// for-each문은 내부적으로 std::initializer_list 안에 들어있는 iterator를 사용하는 구조이다. 이거는 std 라이브러리를 설명할 때 좀 더 자세하게 설명할 것이다.
// 편하게 사용하는 것은 좋은데 다른 사람들이 내가 구현할 것을 미리 구현해준 거기 때문에 어떻게 구현되어있나는 추가적으로 공부해야 된다.
// 어쨌든 공부하는 게 내가 다 구현하는 것보다는 훨씬 편하다. 이거는 뒤에 가서 강의 보면 그냥 이런 거였구나, 이렇게 쓰면 되는구나 하면 되는 거니깐 일단은 이렇게 번거롭더라도 count를 따로 붙여서 구현하는게 더 편하다 정도 생각하면 된다.
~IntArray()
{
delete[] this->m_data;
}
//TODO: overload operator =
// 사실 std::initializer_list을 이용해서 생성자를 구현하면 대입 연산자도 같이 오버로딩해주는게 좋다.
IntArray& operator = (const std::initializer_list<int>& list)
{
cout << "Assignment operator " << endl;
delete[] m_data;
m_length = list.size();
m_data = new int[m_length];
int count = 0;
for (auto& element : list)
{
m_data[count] = element;
++count;
}
return *this;
}
friend ostream& operator << (ostream& out, IntArray& arr)
{
for (unsigned i = 0; i < arr.m_length; ++i)
out << arr.m_data[i] << " ";
out << endl;
return out;
}
};
int main()
{
int my_arr1[5] = { 1, 2, 3, 4, 5 };
int* my_arr2 = new int[5]{ 1, 2, 3, 4, 5 };
auto il = { 10, 20, 30 };
// #include <initializer_list>를 주석처리하면 에러가 난다.
//IntArray int_array = { 1, 2, 3, 4, 5 };
IntArray int_array{ 1, 2, 3, 4, 5 };
int_array = { 1, 2, 3, 4, 5, 6, 7 };
cout << int_array << endl;
return 0;
0
buffer overrun만이 발생하는 것이 맞나요?
첨부하신 소스코드로는 아래와 같이 다수의 에러가 나오는 것 같아서요.
test.cc:9:20: warning: default member initializer for non-static data member is a C++11 extension [-Wc++11-extensions]
unsigned m_length = 0;
^
test.cc:10:14: warning: default member initializer for non-static data member is a C++11 extension [-Wc++11-extensions]
int* m_data = nullptr;
^
test.cc:19:22: error: no template named 'initializer_list' in namespace 'std'
IntArray(const std::initializer_list<int>& list)
~~~~~^
test.cc:34:35: error: no template named 'initializer_list' in namespace 'std'
IntArray& operator = (const std::initializer_list<int>& list)
~~~~~^
test.cc:23:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& element : list)
^
test.cc:23:22: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& element : list)
^
test.cc:44:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& element : list)
^
test.cc:44:22: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& element : list)
^
test.cc:66:27: error: expected ';' at end of declaration
int* my_arr2 = new int[5]{ 1, 2, 3, 4, 5 };
^
;
test.cc:68:2: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto il = { 10, 20, 30 };
^
test.cc:68:12: error: cannot deduce type of initializer list because std::initializer_list was not found; include <initializer_list>
auto il = { 10, 20, 30 };
^
test.cc:72:11: error: no matching constructor for initialization of 'IntArray'
IntArray int_array{ 1, 2, 3, 4, 5 };
^
test.cc:13:2: note: candidate constructor not viable: requires single argument 'length', but no arguments were provided
IntArray(unsigned length)
^
test.cc:6:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class IntArray
^
test.cc:72:20: error: expected ';' at end of declaration
IntArray int_array{ 1, 2, 3, 4, 5 };
^
;
test.cc:73:14: error: expected expression
int_array = { 1, 2, 3, 4, 5, 6, 7 };
^
7 warnings and 7 errors generated.
0
// 기본 자료형으로 array를 만들 때는 initializer_list를 이용해서 값을 편하게 초기화할 수가 있었다.
// 이번에는 class 같은 사용자 정의 자료형에서 생성자나 대입 연산자를 만들 때 편하게 사용할 수 있는 std::initilalizer_list 사용법에 대해서 알아본다.
#include <iostream>
#include <cassert>
#include <initializer_list>
using namespace std;
class IntArray
{
private:
unsigned m_length = 0;
int* m_data = nullptr;
public:
IntArray(unsigned length)
: m_length(length)
{
m_data = new int[length];
}
IntArray(const std::initializer_list<int>& list)
: IntArray(list.size())
// 다른 생성자를 호출해서 메모리를 받아오고 있다. IntArray(unsigned length) 생성자에서 메모리를 받아주고 있다.
{
int count = 0;
for (auto& element : list)
{
m_data[count] = element;
++count;
//m_data[count++] = element;
// C 스타일에 익숙한 사람들은 안에 넣어버리기도 한다.
// 요즘에는 컴파일러도 빨라지고 컴퓨터도 빨라지고 그래서 교수같은 경우는 사람이 실수하지 않도록 분리하는 편이다.
}
//for (unsigned count = 0; count < list.size(); ++count)
// m_data[count] = list[count]; // error
// count가 따로 되어있으니깐 번거로워보여서 옛날 프로그래머들은 이렇게 시도할 수 있다.overrun
// 그런데 std::initializer_list는 대괄호 operator를 제공하지 않는다. std::array나 std::vector에서는 사용할 수 있었는데 std::initializer_list는 제공해주지 않는다.
}
// 그래서 내부적으로 구현이되어있을 때 std::initializer_list 같은 경우는 iterator라는 것을 사용해서 for문을 돌리게 되어있는데
// for-each문은 내부적으로 std::initializer_list 안에 들어있는 iterator를 사용하는 구조이다. 이거는 std 라이브러리를 설명할 때 좀 더 자세하게 설명할 것이다.
// 편하게 사용하는 것은 좋은데 다른 사람들이 내가 구현할 것을 미리 구현해준 거기 때문에 어떻게 구현되어있나는 추가적으로 공부해야 된다.
// 어쨌든 공부하는 게 내가 다 구현하는 것보다는 훨씬 편하다. 이거는 뒤에 가서 강의 보면 그냥 이런 거였구나, 이렇게 쓰면 되는구나 하면 되는 거니깐 일단은 이렇게 번거롭더라도 count를 따로 붙여서 구현하는게 더 편하다 정도 생각하면 된다.
~IntArray()
{
delete[] this->m_data;
}
//TODO: overload operator =
// 사실 std::initializer_list을 이용해서 생성자를 구현하면 대입 연산자도 같이 오버로딩해주는게 좋다.
IntArray& operator = (const std::initializer_list<int>& list)
{
cout << "Assignment operator " << endl;
delete[] m_data;
m_length = list.size();
m_data = new int[m_length];
int count = 0;
for (auto& element : list)
{
m_data[count] = element;
++count;
}
return *this;
}
friend ostream& operator << (ostream& out, IntArray& arr)
{
for (unsigned i = 0; i < arr.m_length; ++i)
out << arr.m_data[i] << " ";
out << endl;
return out;
}
};
int main()
{
int my_arr1[5] = { 1, 2, 3, 4, 5 };
int* my_arr2 = new int[5]{ 1, 2, 3, 4, 5 };
auto il = { 10, 20, 30 };
// #include <initializer_list>를 주석처리하면 에러가 난다.
//IntArray int_array = { 1, 2, 3, 4, 5 };
IntArray int_array{ 1, 2, 3, 4, 5 };
int_array = { 1, 2, 3, 4, 5, 6, 7 };
cout << int_array << endl;
return 0;
}
return 0; 밑에 } 하나가 빠져있었네요 죄송합니다...
변수가 메모리에 저장되는 것을 알려주는 강의가 어떤강의였죠
1
483
1
메모리 주소 10진수로 출력
1
673
1
클래스 템플릿 특수화에서 boolalpha로 표현된 리턴값에 대해 질문이 있습니다.
1
520
1
여러가지 리턴 타입에 관한 강의가 어떤 걸까요?
1
550
1
메모리 주소에 관한 질분
0
689
1
인터페이스 클래스에서 reportError의 매개변수에 대해 궁금한 것이 있습니다.
0
558
1
형변환 오버로딩에서 const 관련 질문이 있습니다.
0
450
1
Digit 뒤에 reference를 사용하는 이유
0
515
1
4.2 전역 변수, 정적 변수, 내부 연결, 외부 연결
0
330
1
dat파일이...
0
544
1
TODO:대입 연산자 오버로딩에 대한 소스코드입니다.
0
654
1
복사 생성자 관련 질문이 있습니다.
0
459
1
수업 중 궁금한점이 있습니다.
1
395
1
라이브러리자체가 이해가 되지 않습니다.
0
570
1
마지막 예제 질문
0
308
1
증감연산자 위치에 따른 수행 순서 질문입니다.
0
384
1
단항 연산자 오버로딩에서 return 부분에 질문이 있습니다.
1
420
1
friend함수 관련 질문이 있습니다.
0
317
1
operator+ 정의부분에서 궁금한 것이 있습니다.
0
452
1
3분 17초 질문
0
358
1
함수에 값을 대입한다는 개념이 이해가 되지 않습니다.
0
454
1
int getvalue() const에서 const는 왜 뒤에 붙는건가요?
0
457
2
const Something &st에서 const를 빼면 안되나요?
0
307
1
friend함수는 다른 클래스의 멤버함수로 쓸 수 없나요??
1
499
1





