-
카테고리
-
세부 분야
프로그래밍 언어
-
해결 여부
미해결
9.12 이니셜라이저리스트 연습문제
23.01.03 12:27 작성 조회수 246
0
#include <iostream>
#include<cassert>
using namespace std;
#include<initializer_list>
class IntArray
{
unsigned mLength = 0;
int *mData = nullptr;
public:
IntArray(unsigned length)
: mLength(length)
{
mData = new int[length];
}
~IntArray()
{
delete[]this->mData;
}
IntArray(const std::initializer_list<int> &list)
: IntArray(list.size())
{
int count = 0;
for ( auto &e : list )
{
mData[count] = e;
++count;
}
}
friend ostream &operator<<(ostream &os, IntArray &arr)
{
for ( unsigned i = 0; i < arr.mLength; ++i )
{
os << arr.mData[i] << " ";
}
os << endl;
return os;
}
//=operator
IntArray& operator=(const std::initializer_list<int> &array)
{
cout << "assignment operator" << endl;
delete[] mData;
mLength = array.size();
if(mData!=nullptr )
{
mData = new int[mLength+1];
//이 부분에서 mData = new int[mLength];로 코딩하면 버퍼 오버런이 뜹는데 오류 메세지를 보면
이렇게 나옵니다 0에서 0사이라는 것이 뭔가요??
int i {};
for ( auto &e : array )
{
mData[i++] = e;
}
}
else
{
mData = nullptr;
}
return *this;
}
};
int main()
{
IntArray intArray = {11,12,13,14,15,16,17,18,19,20};
intArray = {1,2,3,4,5,6,7,8,9,10};
cout << intArray << endl;
}
답변을 작성해보세요.
0
강민철
2023.01.03
대입 과정에서 인덱스를 벗어났습니다.
아래 코드가 힌트가 되었으면 합니다.
첨부한 코드에서
cout << "before assigned : " << i << '\n';
mData[i++] = e;
cout << "after assigned : " << i << '\n';
cout << "mData[" << i << "]" << '\n';
그리고
cout << "mLength is " << mLength << endl;
위 두 코드를 추가했습니다.
$ cat test2.cc
#include <iostream>
#include<cassert>
using namespace std;
#include<initializer_list>
class IntArray
{
unsigned mLength = 0;
int *mData = nullptr;
public:
IntArray(unsigned length)
: mLength(length)
{
mData = new int[length];
}
~IntArray()
{
delete[]this->mData;
}
IntArray(const std::initializer_list<int> &list)
: IntArray(list.size())
{
int count = 0;
for ( auto &e : list )
{
mData[count] = e;
++count;
}
}
friend ostream &operator<<(ostream &os, IntArray &arr)
{
for ( unsigned i = 0; i < arr.mLength; ++i )
{
os << arr.mData[i] << " ";
}
os << endl;
return os;
}
//=operator
IntArray& operator=(const std::initializer_list<int> &array)
{
cout << "assignment operator" << endl;
delete[] mData;
mLength = array.size();
if(mData!=nullptr )
{
// mData = new int[mLength+1];
cout << "mLength is " << mLength << endl;
mData = new int[mLength];
int i {};
for ( auto &e : array )
{
cout << "before assigned : " << i << '\n';
mData[i++] = e;
cout << "after assigned : " << i << '\n';
cout << "mData[" << i << "]" << '\n';
}
}
else
{
mData = nullptr;
}
return *this;
}
};
int main()
{
IntArray intArray = {11,12,13,14,15,16,17,18,19,20};
intArray = {1,2,3,4,5,6,7,8,9,10};
cout << intArray << endl;
}
실행 결과는 다음과 같습니다.
$ ./a.out
assignment operator
mLength is 10
before assigned : 0
after assigned : 1
mData[1]
before assigned : 1
after assigned : 2
mData[2]
before assigned : 2
after assigned : 3
mData[3]
before assigned : 3
after assigned : 4
mData[4]
before assigned : 4
after assigned : 5
mData[5]
before assigned : 5
after assigned : 6
mData[6]
before assigned : 6
after assigned : 7
mData[7]
before assigned : 7
after assigned : 8
mData[8]
before assigned : 8
after assigned : 9
mData[9]
before assigned : 9
after assigned : 10
mData[10]
1 2 3 4 5 6 7 8 9 10
패러그래프
질문자2023.01.03
이전에도 결과는 잘나왔는데 경고로 버퍼 오버런이 발생했다고 나왔거든요
근데 위 두 코드가 어떤게 다른건지 잘모르겠습니다
그리고 이렇게 써도 버퍼오버런이 계속 발생하네요 결과는 같게 나옵니다
강민철
2023.01.03
위 답변에 첨부드린 코드대로 돌려보셨나요?
위 답변을 보시면 알 수 있듯이,
mData[i++] = e;
를 실행되는 과정에서 mData[10]까지 대입되기 때문입니다.
mData[9]까지밖에 선언되지 않았는데 말이지요.
패러그래프
질문자2023.01.03
네 혹시 몰라서 그대로 복붙해서도 돌려봤는데 버퍼 오버런 경고가 나옵니다
mData = new int[mLength+1];로 바꾸면 10까지 선언되서 버퍼 오버런 경고가 사라지는 것 같은데???(맞나요?)
검색하다 보니 저런식으로 9를 10으로 바꾸는 식의 방법은 나중에 문제가 될 수 있다는 글을 봐서요
다른 방법을 찾아봐야 겠습니다 ㅎㅎ
강민철
2023.01.03
위에 첨부드린 코드는 [패러그래프]님께서 버퍼 오버런이 발생한다고 했던 코드를
그대로 갖고 와서 cout 출력 코드만 추가한 코드입니다.
저걸 돌려보면 인덱스가 10까지 출력되는 것을 볼 수 있지요..
10개의 배열만 선언했으면 인덱스가 9까지 나와야 하는데
10까지 찍혔기 때문에 버퍼 오버런이 발생한 겁니다.
그걸 직접 확인해보셨으면 해서 위 코드를 첨부 드린 것입니다..
그렇기 때문에 마찬가지로 new int[mLength+1];로 바꾸면 당연하게도
버퍼 오버런이 발생하지 않습니다.
배열 요소를 11개가 되니까 인덱스 10도 충분히 저장 가능해지니까요..
답변 1