• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

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;

}

답변 1

답변을 작성해보세요.

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

위 답변에 첨부드린 코드대로 돌려보셨나요?

위 답변을 보시면 알 수 있듯이,

mData[i++] = e;

를 실행되는 과정에서 mData[10]까지 대입되기 때문입니다.

mData[9]까지밖에 선언되지 않았는데 말이지요.

네 혹시 몰라서 그대로 복붙해서도 돌려봤는데 버퍼 오버런 경고가 나옵니다

mData = new int[mLength+1];로 바꾸면 10까지 선언되서 버퍼 오버런 경고가 사라지는 것 같은데???(맞나요?)

검색하다 보니 저런식으로 9를 10으로 바꾸는 식의 방법은 나중에 문제가 될 수 있다는 글을 봐서요

다른 방법을 찾아봐야 겠습니다 ㅎㅎ

 

강민철님의 프로필

강민철

2023.01.03

위에 첨부드린 코드는 [패러그래프]님께서 버퍼 오버런이 발생한다고 했던 코드를

그대로 갖고 와서 cout 출력 코드만 추가한 코드입니다.

저걸 돌려보면 인덱스가 10까지 출력되는 것을 볼 수 있지요..

10개의 배열만 선언했으면 인덱스가 9까지 나와야 하는데

10까지 찍혔기 때문에 버퍼 오버런이 발생한 겁니다.

그걸 직접 확인해보셨으면 해서 위 코드를 첨부 드린 것입니다..

그렇기 때문에 마찬가지로 new int[mLength+1];로 바꾸면 당연하게도

버퍼 오버런이 발생하지 않습니다.

배열 요소를 11개가 되니까 인덱스 10도 충분히 저장 가능해지니까요..

음 근데 다른 IDE를 사용하면 아무런 문제도 없고 버퍼 오버런이 뜨지 않습니다... 이건 또 왜 그런건가요??

강민철님의 프로필

강민철

2023.01.04

IDE마다 발생하는 에러는 다를 수 있습니다.