【问题标题】:Valgrind reports invalid read size of 8, but there are no memory leaksValgrind 报告无效读取大小为 8,但没有内存泄漏
【发布时间】:2020-07-21 04:48:07
【问题描述】:

以下是 Valgrind 的报告:

==31109== Invalid read of size 8
==31109==    at 0x400D95: Array_Shellsort (in /home/shay/a/ashanbha/368summer/pa2/pa2)
==31109==    by 0x4006CB: main (in /home/shay/a/ashanbha/368summer/pa2/pa2)
==31109==  Address 0x5207238 is 8 bytes before a block of size 240 alloc'd
==31109==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==31109==    by 0x400A92: Generate_2p3q_Seq (in /home/shay/a/ashanbha/368summer/pa2/pa2)
==31109==    by 0x400CBE: Array_Shellsort (in /home/shay/a/ashanbha/368summer/pa2/pa2)
==31109==    by 0x4006CB: main (in /home/shay/a/ashanbha/368summer/pa2/pa2)
==31109==
31970.000000
==31109==
==31109== HEAP SUMMARY:
==31109==     in use at exit: 0 bytes in 0 blocks
==31109==   total heap usage: 4 allocs, 4 frees, 9,376 bytes allocated
==31109==
==31109== All heap blocks were freed -- no leaks are possible
==31109==
==31109== For lists of detected and suppressed errors, rerun with: -s
==31109== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

以下是生成函数:

  long *Generate_2p3q_Seq (int n, int *seq_size)
  {
    *seq_size = seqsize(n);
    long *sequence = malloc (sizeof(long) * *seq_size);
    printf("size: %d \n",*seq_size);
    sequence[0] = 1;
    int two = 0;
    int three = 0;
    for (int i = 1; i < *seq_size; i++)
    {
      if ((sequence[two] * 2) > (sequence[three] * 3))
      {
        sequence[i] = sequence[three] * 3;
        three++;
      }
      else if ((sequence[two] * 2) < (sequence[three] * 3) )
      {
        sequence[i] = sequence[two] * 2;
        two++;
      }
      else
      {
        sequence[i] = sequence[two] * 2;
        three++;
        two++;
      }
    }
    return sequence;                                                                                          
  }

以下是我的shellsort函数:

 void Array_Shellsort (long *array, int size, double *n_comp)
  {
    int seqsize = 0;
    long * sequencearray = Generate_2p3q_Seq(size,&seqsize);
      long interval = sequencearray[seqsize - 1];
    int i = 1;
    int in,out;
    long temp;
    *n_comp = 0;
    while (interval > 0)
    {
      for (out = interval; out < size; out++)
      {
        temp = array[out];
        in = out;
 
        while (in > interval - 1 && array[in - interval] >= temp)
        {
          array[in] = array[in - interval];
          in -= interval;
          (*n_comp)++;
        }
        array[in] = temp;
        (*n_comp)++;
      }
      i += 1;
      interval = sequencearray[seqsize - i];
    }
    free(sequencearray);
  }

我在 main 中释放了我的实际数组(不是我的序列)。我很好奇是什么导致了 8 的无效读取大小,因为 valgrind 说没有泄漏。我也很好奇这 4 个分配器来自哪里,因为我只为实际数组和序列数组分配。

【问题讨论】:

  • 无效读取意味着您正在访问超出某些已分配数组(或数据)范围的内存。与有无泄漏无关。它说“之前有 8 个字节”;访问数组时,您的索引为 -1 或类似的东西。在创建目标文件和链接时,您需要在启用调试的情况下编译代码(-g 假设 GCC 或 Clang 是您的编译器)。然后你会得到问题所在的行号,通常很容易找到行号的问题。
  • @JonathanLeffler 就是这样,当我运行 gdb 时它会正常退出。
  • GDB 不是 Valgrind——他们做不同的工作。 Valgrind 告诉你程序中有一个严重的错误。为了从 Valgrind 中获得最大的好处,您必须在启用调试的情况下进行编译。然后,您使用 Valgrind 而不是 GDB 运行该代码,以找出您的代码哪里出错了。由于您的代码不是一个完整的程序——它不是 MCVE (Minimal, Complete, Verifiable Example)(或 MRE 或 SO 现在使用的任何名称),也不是 SSCCE (Short, Self-Contained, Correct Example)——尚不清楚其他人是否可以重现您的问题。
  • 您确定Generate_2p3q_Seq() 确实返回 0 的seqsize,因此读取sequencearray[seqsize - 1] 的下一行使用-1 的索引?
  • @thebusybee 我很确定。但如果你好奇的话,我想出了问题所在。这两行: i += 1;间隔 = 序列数组 [seqsize - i];是 -1 索引无效读取的来源。我只是在那里放了一个 if 语句来检查它,如果它是无效的就打破它。

标签: c valgrind shellsort


【解决方案1】:

我想出了问题的答案。这两行导致问题:

i += 1;
interval = sequencearray[seqsize - i];

这可以通过一个简单的 if 语句来解决,如果它是无效的(条件是 seqsize - i

【讨论】:

    猜你喜欢
    • 2016-04-25
    • 1970-01-01
    • 2017-07-17
    • 2020-09-17
    • 1970-01-01
    • 2017-06-29
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多