0

私は大学向けのプロジェクトを書いています。すべて完了し、すべてのテストに合格し、正常に動作しますが、valgrind は次のように言います。

==8059== Invalid read of size 8
==8059==    at 0x406E4E: RegPoly::getCurrentCoefficient() const (RegPoly.cpp:59)
==8059==    by 0x403368: MyPoly::operator+(MyPoly const&) const (MyPoly.cpp:281)
==8059==    by 0x403A6D: MyPoly::operator+=(MyPoly const&) (MyPoly.cpp:354)
==8059==    by 0x401E20: main (DemoPoly.cpp:50)
==8059==  Address 0x5953f50 is 0 bytes after a block of size 16 alloc'd
==8059==    at 0x4C27297: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8059==    by 0x4060CD: __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) (new_allocator.h:92)
==8059==    by 0x405934: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) (in /a/fr-05/vol/home/stud/lablabla/CppLab/Ex3/DemoPoly)
==8059==    by 0x407355: double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) (stl_vector.h:1052)
==8059==    by 0x40700E: std::vector<double, std::allocator<double> >::operator=(std::vector<double, std::allocator<double> > const&) (vector.tcc:167)
==8059==    by 0x406C5D: RegPoly::RegPoly(RegPoly const&) (RegPoly.cpp:19)
==8059==    by 0x4031DB: MyPoly::operator=(MyPoly const&) (MyPoly.cpp:249)
==8059==    by 0x403B58: MyPoly::operator*=(MyPoly const&) (MyPoly.cpp:364)
==8059==    by 0x401DB6: main (DemoPoly.cpp:44)

台詞:

44 -p3 *= p2; // both are MyPoly objects

50 -p3 += p1;

変更された(?)メモリから読み込もうとしているということはなんとなくわかりますが、その理由はわかりませんでした。関連するコードを投稿できますが、質問が面倒になるため、どの部分かわかりません。関連する部分を貼り付けることができます。必要なものを教えてください。

ありがとう!

編集:コードは次のとおりです。

MyPoly& MyPoly::operator *=(const MyPoly& rhs)
{
    *this = *this * rhs; // 364
    return *this;
}

===================

case PolyInterface::REG:
{
    RegPoly *tempReg = dynamic_cast<RegPoly*>(rhs.p_PolyBody); // rhs is an interface, hence the dynamic cast
    if (tempReg != NULL)
    {
        p_PolyBody = new RegPoly(*tempReg);  // 249. p_PolyBody is a pointer stored in MyPoly. points to RegPoly object
    }
    break;
}

===================

RegPoly::RegPoly(RegPoly const& other)
{
    gCurrentRank = 0;
    gData = other.gData; // 19. gData is a vector<double>
    _isZeroPoly = other._isZeroPoly;
}

===================

double RegPoly::getCurrentCoefficient() const
{
    return *gDataIterator; // 59. vector<double>::const_iterator
}

===================

newPolyValues.push_back(
                p_PolyBody->getCurrentCoefficient() + rhs.p_PolyBody->getCurrentCoefficient());
// 281.

getCurrentCoefficient()編集:返されたときにもこれを取得していますgData[gCurrentRank] 。つまり、gData 自体の場所に関するものですよね?

登録ポリ:

std::vector<double> gData;
std::vector<double>::iterator gDataIterator;
int gCurrentRank;
bool _isZeroPoly; // Inherited from the interface
4

2 に答える 2

1

valgrind を信頼してください。ほとんどの場合、既存の問題が表示されます。

メッセージの読み方は次のとおりです。

RegPoly::getCurrentCoefficient() const (RegPoly.cpp:59)アプリに属していないため(割り当てられていない、スタックではないなど...)、読み取るべきではないメモリ位置から読み取ろうとしました。この無効なアドレスは、新しい演算子で割り当てられ、RegPolyコピー コンストラクターで使用されたスペースをわずかに超えていました (その呼び出しを作成したバックトレース全体を確認できます)。

これで十分でない場合は、関連するコードを投稿してください。

アップデート:

あなたのコピー コンストラクターがコピーしているとは思えませんgDataIterator(ところで、コピーするとき、なぜgCurrentRank0 に初期化するのですか?)。

于 2012-09-06T22:04:01.327 に答える
1

問題は、DemoPoly.cpp:50 ではなく RegPoly.cpp:59 にあります。

16 バイトを割り当てたと言われていますが、割り当てを超えて 8 バイトを読み取ろうとしています。

これを参照してください: http://valgrind.org/docs/manual/mc-manual.html#mc-manual.errormsgs

編集

おそらく、無効な反復子にアクセスしようとしています。const イテレーターは、このイテレーターを使用してコンテナー内の値を変更できないことを意味します。

編集 2

無効なイテレータに関する簡単な説明。

于 2012-09-06T22:04:28.940 に答える