【发布时间】: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 来自哪里?也许错误出现在
ResetSize、SetMaxVal或SetPixels或GetPixels()内部,您还没有显示这些代码。例如,这实际上可能是GetPixels中的缓冲区溢出。 -
在启用调试信息和禁用优化的情况下编译您的代码(
-O0 -g用于 gcc/clang),您将从 valgrind 中获得更好的消息 - 包括行号。 -
@MattMcNabb 像素定义只是一个带有 unsigned char r, g, b 数据成员的结构。有问题的析构函数只做 free(buffer);缓冲区=空; Shrinker 驻留在从 Filter 继承的 Filters 中,Update() 函数通过管道推送我的驱动程序中的所有内容。