0

Segfault 我发现自己无法诊断。

我有一个基准函数chrono,它接收一个strings指向随机生成的字符串的指针数组,以及一个对应的sizes. 对于调试,我打印strings(指向指针的指针)、strings[1](其中之一)和sizes(指针)。(可以肯定的是,我还在 中打印了一些字符串chrono,并与生成它们的 func 中的原始内容进行比较:到目前为止一切都很好。)要进行基准测试的是一个将一组字符串输入字符串的 func水池:

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

对于调试,我在 pool_store_pack 中打印相同的数据。而且价值观不同。strings已更改,并且两者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

好的运行!实际上有 2 个错误,它们相互交互。首先,错误地重新定义了一个静态常量,该常量给出了初始字符串集合的大小以提供给池(实际上只有"",所以这个集合的长度为 1)。其次,2条指令的反转使池在初始化之前被使用。交互是初始化还使用 pool_store_pack 为池提供所述初始字符串。

==>

我得到的调试输出(并向您展示)反映了调用此 func pool_store_pack 进行池初始化的数据,而不是来自 chrono func(因此,strings[1]为零,因为初始集中只有一个字符串!)。并且sizes是 nil,因为它是静态常数错误地改变了......妈妈咪呀!

谢谢大家!不幸的是,我不能投票给你,因为只有评论......

于 2012-12-13T22:22:20.743 回答