【问题标题】:Segmentation fault when different input is given给出不同输入时的分段错误
【发布时间】:2010-01-20 04:34:00
【问题描述】:

我用 C++ 做一些图像处理工作。为此,我使用 CImg.h 库,我觉得这对我的工作很有帮助。

这是我编写的一小段代码,它只是读取图像并显示它。

#include "../CImg.h"
#include "iostream"

using namespace std;
using namespace cimg_library;

int main(int argc,char**argv)
{
     CImg<unsigned char> img(argv[1]);
     img.display();  
     return 0;  
}

当我将 lena.pgm 作为输入时,此代码会显示图像。好像我给出了其他图像,例如我在同一目录中出现的 ddnl.pgm,我得到“分段错误”。

当我使用 gdb 运行代码时,我得到如下输出:

程序收到信号 SIGSEGV,分段错误。
/lib/libc.so.6 中的 strlen() 中的 0x009823a3
缺少单独的调试信息,使用:debuginfo-install glibc-2.9-2.i686 libX11-1.1.4-5.fc10.i386 libXau-1.0.4-1.fc10.i386 libXdmcp-1.0.2-6.fc10.i386 libgcc -4.3.2-7.i386 libstdc++-4.3.2-7.i386 libxcb-1.1.91-5.fc10.i386

谁能告诉我问题是什么?以及如何解决。

谢谢大家

【问题讨论】:

  • 这不太可能与您的问题有关,但我认为#include &lt;iostream&gt; 被认为比#include "iostream" 更好
  • 两张图有区别吗?例如,一个明显更大吗?
  • 接受文件名的 CImg 构造函数可能会引发异常 (bit.ly/6hYyoi)。此外,您没有检查 argc ,因此请查看 argv[1] 是否已定义。不确定是不是这样,有点猜测。您是否尝试在像 gdb 这样的调试器下运行它?如果它在 gdb 中捕获到异常,请键入“backtrace”以查看发生了什么。
  • 您说的是后续运行完全相同的程序,只是参数不同?另外,您使用的是什么版本的 CImg?
  • ddnl.pgm 是 PGM 图像文件还是其他什么?从 ux9i 的链接中,它尝试根据文件的扩展名确定图像类型。

标签: c++ segmentation-fault cimg


【解决方案1】:

当您尝试访问不允许访问的内存时会出现段错误。 所以请在代码中检查一下。

【讨论】:

  • 为什么投反对票?它是正确的。不确定这是否相关,但鉴于我们得到的信息很少,他可能是对的。
【解决方案2】:

代码本身看起来还不错。我可以建议一些继续调试的方法 -

  1. 尝试删除 display() 调用。问题是否仍然存在? (我认为确实如此)。
  2. 尝试找出 CImg 代码中导致分段错误的 strlen() 的位置(通过使用调试器)。这可能会提供额外的提示。
  3. 如果它在 PGM 文件处理中,可能提供的 PGM 文件在某些​​方面无效,并且库不进行错误检测 - 尝试在其他查看器中打开它,然后再次保存(作为 PGM)。如果新的有效,比较两者可能会发现一些东西。

一旦你有了更多的信息,就可以说更多。

编辑 -

查看您提供的额外信息并查阅代码本身,CImg 在尝试检查您打开的文件类型时似乎失败了。

相关的代码行是-

if (!cimg::strcmp(ftype,"pnm")) load_pnm(filename);

这是第一次使用'ftype',这让我得出结论,它的值无效。

'ftype' 在上面几行被赋予了一个值 -

const char *const ftype = cimg::file_type(0,filename);

file_type() 函数本身尝试根据文件头来猜测要打开的文件,可能是因为根据扩展名打开文件失败了。它只有一种理智的方法可以返回无效值,这会导致 strcmp() 失败 - 当它无法将文件识别为它熟悉的任何内容时,它会返回 NULL(实际上是 0)。

所以,我重申我的建议,即您尝试验证这确实是一个有效文件。我无法指出任何能够打开/保存 PGM 文件的工具,但我猜一个简单的谷歌搜索会有所帮助。尝试打开文件并将其重新保存为 PGM。

【讨论】:

  • 嗨六边形,非常感谢您的回复...我会尝试您的这些建议。我没有注意到评论部分。对于下一篇文章,我将使用它。谢谢。有没有办法检查 PGM 文件的有效性?我会以任何方式谷歌搜索它。如果您知道,请不要介意分享。还有一件事,我使用 Matlab 的 imwrite 功能来创建这些 PGM 文件。我会随时相信 Matlab 的输出,因为我的许多算法都使用 matlab 证明是正确的。我认为它应该提供有效的 PGM 文件作为输出。
  • @sravan,我倾向于同意你的观点——我也会信任 Matlab。但由于 PGM 格式不是很严格,两者之间可能存在一些不兼容。不,我不是检查 PGM 文件有效性的好方法。您可能需要逐步检查 CImg 代码并确切了解它是如何失败的 - 它可能会提示您 PGM 文件有什么问题。
  • 嗨 hexagon,昨天,我通过 Internet 下载了几个 pgm 文件并尝试使用这些新图像使用相同的程序。答对了!!有效。只是为了让自己满意,我在 linux 上使用 GIMP 打开了一个 JPG 图像并转换为 PGM 文件。甚至新创建的 pgm 文件也可以与 CImg 一起使用。因此,我得出的结论是,只有在 Matlab 中使用 imwrite 创建的 PGM 图像给我带来了一些问题。我不知道 Matlab 的错误 imwrite 是生成错误的 PGM 文件还是与 CImg 相关。因为我必须继续我的工作,所以我正在使用下载的 pgm 文件。谢谢六边形
【解决方案3】:

另一个导致分段错误的“有趣”原因是库之间的编译器不匹配——这在使用 C++ 库时尤其普遍。

要检查的事项是:

  1. 您是否使用与编译 CImg 库相同的编译器进行编译?
  2. 您是否使用相同的编译器标志?
  3. 编译库时是否设置了您现在没有设置的定义?

这些都曾以微妙的方式咬过我。

【讨论】:

  • 总的来说,这些建议是合理的。但特别是对于 CImg 库,它看起来只是存在于一个大(非常大......)头文件中。所以单独的编译不应该是一个问题 - 没有什么可以链接到。
  • 确实,为 CImg 本身草拟这些想法。但是在查看 CImg 文档之后,它会将某些格式的读/写转发给可能存在这些问题的其他库。然而,这些库主要是 C 库,因此不太容易受到此类问题的影响。
猜你喜欢
  • 2016-05-21
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2019-02-23
相关资源
最近更新 更多