1

質問は下に太字で示されています:

これは正常に機能します。

void process_batch( 
  string_vector & v
) 
{

  training_entry te;
  entry_vector sv; 
  assert(sv.size() == 0);
...
}

ただし、これによりアサートが失敗します。

   void process_batch( 
      string_vector & v
    ) 
    {
      entry_vector sv; 
      training_entry te;
      assert(sv.size() == 0);
      ...
   }

この問題はシュリンクラップではないことがわかったので、質問をこれに限定します。どのような条件がこのような問題を引き起こす可能性がありますか?具体的には、スタックフレームの出現順序に応じて、変数の初期化が破損します。私のコードにはmallocやfreeはなく、strcpy、memcpyなどの安全でない関数もありません...これは最新のc++です。使用したコンパイラ:gccおよびclang。

簡潔にするために、ここにタイプがあります

struct line_string
{
  boost::uint32_t line_no;
  std::string     line;
};

typedef  std::vector<boost::uint32_t> line_vector;
typedef std::vector<line_vector> entry_vector;
typedef std::vector<line_string> string_vector;

struct training_body
{
  boost::uint32_t url_id;
  bool relevant;
};

struct training_entry
{
  boost::uint32_t session_id;
  boost::uint32_t region_id;
  std::vector< training_body> urls;
};

ps、コンパイラに問題があると言っているわけではありません。おそらく私のコードです。しかし、私はずっと前に書いたコードをテンプレート化しているので、問題は私を完全に困惑させ、問題を見つけるためにどこを探すべきかわかりません。

編集

nimの提案に従い、次のループを通過しました

  1. コードをここに示したものにシュリンクラップし、コンパイルしてテストします。問題ありません。
  2. #if 0 #endifメインプログラムをシュリンクラップします。
  3. シュリンクラップ形式でコンパイルされるまでヘッダーを削除します。
  4. シュリンクラップ形式でコンパイルされるまでライブラリリンクを削除します。

解決策:プロトコルバッファへのリンクを削除すると、問題が解消されます

4

4 に答える 4

4

C ++標準は、次のアサーションが成功することを保証します。

std::vector<anything> Default; 
//in your case anything is line_vector and Default is sv
assert(Default.size() == 0);

つまり、全体像を伝えていないか、STLの実装が壊れているかのどちらかです。

または:コードに未定義の動作があります。C ++標準は、UBにつながる構造を持つプログラムの動作について、その構造に到達する前であっても、保証を提供しません。

于 2012-02-01T15:45:15.967 に答える
3

作成されたオブジェクトの1つがコンストラクターでその終わりを超えて書き込む場合、これの通常のケース。そして、これが私が見たコードで発生する最も頻繁な理由は、オブジェクトファイルが異なるバージョンのヘッダーでコンパイルされていることです。たとえば、ある時点で、クラスの1つのデータメンバーを追加(または削除)し、それを使用するすべてのファイルを再コンパイルしませんでした。

于 2012-02-01T15:50:30.127 に答える
1

表示される種類の問題の原因となる可能性があるのは、コンストラクターの動作が正しくないユーザー定義型です。

class BrokenType {
  public:
  int i;
  BrokenType() { this[1].i = 9999; } // Bug!
};

void process_batch( 
  string_vector & v
) 
{

  training_entry te;
  BrokenType b;  // bug in BrokenType shows up as assert fail in std::vector
  entry_vector sv; 
  assert(sv.size() < 100);
...
}
于 2012-02-01T15:46:33.453 に答える
1

プラットフォームに適したBoostライブラリの適切なバージョンがありますか?(64ビット/ 32ビット)?entry_vectorオブジェクトには、boost::uint32_t型のメンバー変数がいくつかあるようです。実行可能ファイルが1つのプラットフォーム用にビルドされ、ロードされたBoostライブラリが別のプラットフォームのものである場合の動作はわかりません。

于 2012-02-01T16:03:48.390 に答える