【问题标题】:Valgrind Invalid Read ErrorValgrind 无效读取错误
【发布时间】:2015-06-12 03:31:18
【问题描述】:

我无法确定 Valgrind 错误的确切原因:

==3868== Invalid read of size 2
==3868==    at 0x100001F1F: Shrinker::Execute() (in ./proj4B)
==3868==    by 0x1000029CD: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==  Address 0x100c12040 is 0 bytes inside a block of size 7,201,152 free'd
==3868==    at 0x10000D94F: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3868==    by 0x100001BD5: PNMreader::Execute() (in ./proj4B)
==3868==    by 0x100001954: Source::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)

我认为这是由于我在 Shrinker::Execute() 中的嵌套循环和/或它的析构函数:

void Shrinker::Execute() {
    int inWidth = 0, inHeight = 0, maxVal = 255;
    int halfWidth = 0, halfHeight = 0;

    inWidth = img1->GetWidth();
    inHeight = img1->GetHeight();

    halfWidth = inWidth / 2;
    halfHeight = inHeight / 2;

    buffer = (Pixel *) malloc(sizeof(Pixel)*halfWidth*halfHeight);

    int in = 0, out = 0;
    for (int i = 0; i < halfHeight; i++) {
        for (int j = 0; j < halfWidth; j++) {
            in = i*2*inWidth+j*2;
            out = i*halfWidth+j;
            buffer[out] = img1->GetPixels()[in];
        }
    }

    img.ResetSize(halfWidth, halfHeight);
    img.SetMaxVal(maxVal);
    img.SetPixels(buffer);

}   // end Shrinker::Execute()

我已尝试对 Shrinker 中的嵌套循环和 malloc 进行所有我能想到的细微调整,但无济于事。它的析构函数释放缓冲区并将其设置为 NULL。任何指导将不胜感激。

【问题讨论】:

  • 显示Pixel的定义。 malloc 不应该在 C++ 中使用,因为它实际上并没有开始具有非平凡构造函数的对象的生命周期
  • 如果您怀疑析构函数有问题,显示该析构函数会很有用
  • Filter::Update 来自哪里?也许错误出现在ResetSizeSetMaxValSetPixelsGetPixels() 内部,您还没有显示这些代码。例如,这实际上可能是GetPixels 中的缓冲区溢出。
  • 在启用调试信息和禁用优化的情况下编译您的代码(-O0 -g 用于 gcc/clang),您将从 valgrind 中获得更好的消息 - 包括行号。
  • @MattMcNabb 像素定义只是一个带有 unsigned char r, g, b 数据成员的结构。有问题的析构函数只做 free(buffer);缓冲区=空; Shrinker 驻留在从 Filter 继承的 Filters 中,Update() 函数通过管道推送我的驱动程序中的所有内容。

标签: c++ memory valgrind


【解决方案1】:

实际上,我不知道您的代码的用途。但是,也许你在下面的代码中使用了错误的参数:

in = i*2*inWidth+j*2;

应该是:

in = i*2*halfwidth+j*2;

我认为。

【讨论】:

  • 我不认为这是原因,看起来代码产生了一个倾斜的图像,我仍然得到相同的 valgrind 错误。不过感谢您的意见!
【解决方案2】:

我在这里猜测,但是因为它访问了一个之前已经释放的块 - 某些东西正在破坏在 Shrinker::Execute 中分配的缓冲区 - 如果唯一释放的地方是你的析构函数,那么您可能已经为您的Shrinker 创建了一个错误的(可能是临时的)副本 - 例如,如果您从函数返回一个 Shrinker 对象,就会发生这种情况。

您需要确保您已阻止创建副本或正确实现了复制构造函数和赋值运算符。

【讨论】:

    猜你喜欢
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2015-09-11
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多