0

Segfault 診断できません。

ランダムに生成された文字列へのポインターの配列と、対応chronoする. デバッグのために、(ポインターへのポインター)、(それらの 1 つ)、および(ポインター) を出力します。(確かに、いくつかの文字列を に出力し、それらを生成する func の元の内容と比較します。そこまでは問題ありません。) ベンチマーク対象となるのは、文字列のパックを文字列にフィードする func です。プール:stringssizesstringsstrings[1]sizeschrono

void pool_store_pack (StringPool * pool,
     char ** strings, size_t * sizes, uint n_new);

デバッグのために、同じデータを pool_store_pack 内に出力します。そして価値観が違う。が変更され、とstringsの両方が null です。出力例を次に示します。strings[1]sizes

strings:0x9842fa8 (n°1:0x984200c)
sizes:0x9843f48
some strings: `@PR` `MOB` `TBQ`

strings:0x804a824 (n°1:(nil))
sizes:(nil)
segmentation fault (core dumped)

私はバグをより単純な形に縮小しようとしましたが、ライブラリの自律的な部分を駆動するのはアプリ コードではなくテスト コードであるため、正確には困難です。バグを最初から再現しようとすると、期待どおりに、受信側の関数と送信側の関数で同じ値を持つポインターへのポインターが取得されます。ただし、役立つ場合は、関連する 3 つの関数のコードを投稿できます (ただし、他の関数を駆動するだけなので、実行することはできません)。

私は明らかなポイントを見逃していると確信していますが、それを見ることができず、ブロックされて何時間もイライラしています;-) 助けてもらえますか?

編集:したがって、関連するコード全体は次のとおりです。

/*  Put pack of strings in pool.
*/
void pool_store_pack (StringPool * pool,
         char ** strings, size_t * sizes, uint n_new) {
   pool_grow(pool, n_new);

   // debug /////////////////////////////////////////////////////////
   printfl("n_new:%u", n_new);
   printfl("strings:%p (n°1:%p)", strings, strings[1]);
   printfl("sizes:%p", sizes);
   printfl("some sizes: %u %u %u", sizes[1], sizes[3], sizes[9]);
   printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]);
   end();

   uint i;
   for (i = 0; i < n_new; i++) pool_store(pool, strings[i], sizes[i]);
}

// generate random strings (constants used here are defined somewhere else)
static char ** data_strings (char ** p_bytes) {
   char * bytes = malloc(n_strings * l * sizeof(char));
   check_mem(bytes);
   char ** strings = malloc(n_strings * sizeof(char *));
   check_mem(strings);
   char * s;
   uint i,j;
   srandom(time(NULL));

   for (i=0; i<n_strings; i++) {
      s = bytes + i*l;
      s[size] = NUL;
      for (j=0; j<size; j++) s[j] = '@' + random()%n_letters;
      strings[i] = s;
   }

   //~ for (i=0; i<n_strings; i++) printf("'%s' ", strings[i]); line();
   printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]);
   * p_bytes = bytes;
   return strings;
}

// benchmark
static void chrono () {
   printfl ("=== chrono pool ===============================================");
   uint i;
   clock_t t1, t2;
   float dt;

   // test data string
   char * bytes;
   char ** strings = data_strings(& bytes);
   // string sizes are all equal to size (3)
   size_t * sizes = malloc(n_strings * sizeof(size_t));
   check_mem(sizes);
   for (i=0; i<n_strings; i++) sizes[i] = size;

   // debug ///////////////////////////////////////////////////////////////////
   printfl("n_strings:%u", n_strings);
   printfl("strings:%p (n°1:%p)", strings, strings[1]);
   printfl("sizes:%p", sizes);
   printfl("some sizes: %u %u %u", sizes[1], sizes[3], sizes[9]);
   printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]);

   // now, feed the pool
   StringPool * pool = stringpool();
   t1 = clock();
   pool_store_pack(pool, strings, sizes, n_strings);
   t2 = clock();
   end();
   dt = 1.0 * (t2 - t1) / CLOCKS_PER_SEC;
   print("pool data   : "); show_pool_data(pool);
   print("pool stats  : "); show_pool_stats(pool, false);
   printfl("time  : %.3f", dt);

   free(bytes);
   free(strings);
}
4

1 に答える 1

2

OKラン!実際には、相互に作用する 2 つのバグがありました。まず、プールにフィードする文字列の初期セットのサイズを指定する静的定数の再定義が間違っています (実際には だけ""なので、このセットの長さは 1 です)。第 2 に、初期化前に使用されるプールを作成する 2 つの命令の反転。相互作用は、初期化でも pool_store_pack を使用して、プールに上記の初期文字列を供給することです。

==>

私がデバッグ出力として得た (そしてあなたに示した) ものは、プールの初期化のためにこの func pool_store_pack を呼び出すことからのデータを反映していstrings[1]ました。そしてsizes、静的定数が誤って変更されたため、nil でした... Mama mia!

皆さんに感謝します!残念ながら、コメントしかないので、あなたに投票することはできません...

于 2012-12-13T22:22:20.743 に答える