1

この問題は多くの忙しい機能の最中に発生しているので、それで十分であることを期待して、擬似コードで問題を説明しようと思います。根本的な問題を解決するのと同じように理解することに興味があるので、修正に加えて説明をいただければ幸いです。ありがとう!

「methodOne」は、別の関数からstd :: string xxを取得し、それを文字列x1、x2、およびx3(すべて新しいオブジェクトから)とともに「methodTwo」に送信します。

bool methodOne(...) {
    Object1 obj = Object1(...);
    string xx = obj.someFunction(...);
    methodTwo(xx, obj.getX1(), obj.getX2(), obj.getX3() );
    ...
    return true;
}

次に、「methodTwo」(Object2内)はこれらの文字列を1つのベクトルに結合し、「methodThree」に渡します。

bool Object2::methodTwo(const string xx, const string x1, const string x2, const string x3) {
   vector<string> holder;      // alternate - comment out this line
   holder.push_back(xx);       //             and this line,
   // vector<string> holder(1, "test");    // alternate - uncomment this line
   holder.push_back(x1);
   holder.push_back(x2);
   holder.push_back(x3);
   ...
   obj3.methodThree( holder );
   ...
   return true;
}          // line 443 - where error is backtraced to

最後に、「methodThree」は最終的にいくつかのファイルを作成し、4つの文字列すべてがそのうちの1つに出力されます。

プログラムを実行すると、gdbからセグメンテーション違反が発生します。

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 0x00007fff8f1e3aa2 in std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::~basic_string () (gdb) where
#0  0x00007fff8f1e3aa2 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string ()
#1  0x0000000100009f18 in std::_Destroy<std::string> ()
#2  0x0000000100009f3e in std::__destroy_aux<std::string*> ()
#3  0x0000000100009f9f in std::_Destroy<std::string*> ()
#4  0x0000000100009fd7 in std::_Destroy<std::string*, std::string> ()
#5  0x0000000100060115 in std::vector<std::string, std::allocator<std::string> >::~vector (this=0x7fff5fbfd488) at stl_vector.h:271
#6  0x0000000100013b9f in Station::methodTwo (this=0x7fff5fbff110, foreFN=@0x7fff5fbfdf08, startDT=@0x7fff5fbfded8, stopDT=@0x7fff5fbfdea8, numElems=169, tCase=0x7fff5fbfe7c8) at Station.cpp:443
#7  0x0000000100002b45 in methodOne ()
#8  0x000000010000707a in main ()

'methodTwo'で、文字列'xx'をランダムなテスト文字列に置き換えると、エラーはなくなります。したがって、問題は「xx」にある必要があります。これは、Object1objからのものではない「methodOne」の唯一の文字列でもあります。

一部のコンストラクターは実際には文字列を複製していないと思っていたので(用語を浅くコピーしていますか?)、methodTwoを次のように呼び出すなどのことを試みました。

methodTwo( string(xx), obj.getX1() ...)

または、次のようなものを使用してベクトルを構築する場合

holder.push_back( string(xx) );

しかし、それらはどちらも機能しませんでした。

私は完全に途方に暮れています、私は誰かが持っている助け/ヒントをいただければ幸いです。問題を再現できる一貫性のあるコード、または実際のコードさえも与えていないので、私はその迷惑を知っています---しかし、うまくいけば、これは私より賢い人が何かを見るのに十分です。

ありがとう


新しい奇妙さ:

以下のコメントから、実際のエラーはどこか別の場所にあり、ヒープに感染している可能性が非常に高いようです。しかし、から取得されないxxことによってのみ区別されるため、オブジェクトに追加しようとしました---つまり、以前に呼び出された別のメソッドでは、変数は以前と同じ結果の値に設定されます...objxxxx

string Object1::someFunction(...) {
    ...
    string val = ...;
    setXX(val);
    cout << getXX() << endl;         // this *correctly* prints the value of xx
    ...
    return val;
}
void Object1::setXX(string temp) { xx = string(temp); }
string Object1::getXX() { return xx; }

methodTwo次に、呼び出しでxxを取得します。

methodTwo(obj.getXX(), obj.getX1() ... );

そしてそれはエラーを止めました、しかし xx 文字列を保存しません!!! つまり

obj.someFunction(...);          // this is able to set and retrieve xx
cout << obj.getXX() << endl;    //  prints **blank line!!**
methodTwo(obj.getXX(), obj.getX1() ...);   // no more error, x1 x2 x3 are fine, xx is empty!

今、私は夢中になっているような気がします。

4

1 に答える 1

2

メモリ アロケータ内でクラッシュした場合、クラッシュの瞬間に解放された (または割り当てられた) 正確なメモリに問題を追跡できることはほとんどありません。アロケーターには、通常、無効なポインター (割り当ての先頭を指していないポインター、ヒープの境界外のポインター、重複した解放など) を解放しようとする試みをキャッチするサニティ チェックがあります。メモリ アロケータでのクラッシュの最も一般的な原因は、ヒープの破損です。多くの場合、解放されたチャンクは、チャンクの先頭にある小さな構造を使用して、他の空きチャンクにチェーンされます。解放されたメモリに書き込むか、割り当てられたブロックを超えて書き込むと、これらのポインターが破損し、アロケーターでクラッシュが発生します。

最初のクラッシュを回避した後、代替プログラムが十分長く実行された場合、最終的には別のクラッシュが発生すると予想されます。あなたが観察したパターンはxx、長さが..とxxは大きく異なり、したがって別のメモリプールから割り当てられているという単純なものかもしれません。x1x3

return試すテストは次のとおりmethodThreeです。

于 2012-11-11T21:38:40.417 に答える