【问题标题】:C++ command line utility input file location changes behaviourC++ 命令行实用程序输入文件位置更改行为
【发布时间】:2013-07-16 05:23:52
【问题描述】:

我编写了一个命令行实用程序,用于从 DXF 文件中提取文本。我的实用程序被命名为drawingtotext。假设这样的目录结构(Linux OS):

/home/dave/dxfs/

在 dxfs 文件夹中有一堆 DXF 文件。从那个位置,假设存在一个名为“P1-1522-YI-WD-0403r1.dxf”的文件,像这样运行drawingtotext会失败:

drawingtotext P1-1522-YI-WD-0403r1.dxf

有错误:Segmentation fault (core dumped)

运行 drawingtotext ~/dxfs/P1-1522-YI-WD-0403r1.dxf 给了我我期望的结果,最后加上这个:

*** Error in 'drawingtotext': free(): invalid next size (fast): 0x0000000002031170 ***

带有回溯和巨大的内存映射。

现在,将该文件向上移动到一个目录(/home/dave/ 而不是 /home/dave/dxfs/)会得到我正在寻找的结果而没有错误。将文件重命名为“mydxf.dxf”之类的名称并将其保存在 /home/dave/dxfs/ 中也可以解决此问题。

我的问题是文件的位置如何以及为什么会改变我的程序的行为,我该如何解决?

代码在这里:http://www.github.com/davidworkman9/drawingtotext/

主文件名为“AutoCADConverter.cpp”

【问题讨论】:

  • 一个明显的问题是您没有正确管理资源,使用 RAII。您正在使用拥有原始指针和new/delete。请改用std::unique_ptr
  • 大部分代码不是我写的,它是我修改的一个实用程序,让它做我想做的事情,它是在智能指针成为标准的一部分之前编写的。话虽如此,我的问题是如何简单地更改文件名来解决问题?
  • 程序很可能在某处有未定义的行为,因此看似无害的输入差异会导致出乎意料的不同输出。例如,更改输入文件名长度可能会更改缓冲区的大小,并且根据缓冲区的大小,可能会发生或不发生一些潜在的越界访问。
  • 有一些工具可以帮助找出问题所在;您可以将编译器上的警告级别调高以捕捉一些简单的事情;如果您的编译器提供或您可以访问静态分析器,它可能会发现更复杂的问题。还有一些工具可以让您的程序动态检测 UB,例如 clang's -fsanitize toolsvalgrind

标签: c++ linux command-line command-line-arguments dxf


【解决方案1】:

对于drawingtotext P1-1522-YI-WD-0403r1.dxf 命令的第一个错误,您确定可执行文件与 P1-1522-YI-WD-0403r1.dxf 位于同一文件夹中吗?

第二个错误发生在您释放尚未分配的内存时。通过查看您的代码,此错误必须发生在接近末尾的 delete inputdelete output 行上,因为这是您释放任何内存的唯一地方。
你说

“运行它给了我我期望的结果加上最后的这个[错误]?”

如果输出是按照您的意愿创建的,并且唯一错误的是这个错误,那么您可以通过添加来解释它:

if (input != null) delete input;
if (output != null) delete output;

以避免释放未分配的内存。但是,如果输出正确,就像您说的那样,这只会解决您的问题,这有效,但它可能表示更大的错误。

您应该使用 Strace 运行该程序,这样您就可以在 seg 错误和 free() 错误之前看到系统调用。

【讨论】:

  • 可执行文件位于 /usr/local/bin 中,因此它是全局的。我尝试将输入和输出包装在空检查中,但没有成功。如果我的输入文件是“P1-1522-YI-WD-0403r1.dxf”并且我将其更改为“P1-1522-YI-WDA-0403r1.dxf”(区别是在“YI-WD”之后添加“A” ) 错误不会出现,一切运行正常...我会尝试使用 Strace。
  • if (input != null) delete input; 不会改变任何东西。 delete 一个空指针已经完全合法了; delete 被定义为在给定空指针时不执行任何操作。
  • @bames53 抱歉,我主要用 C 编写代码。所以如果是这样的话,那么免费错误对我来说没有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 2013-08-14
  • 2011-12-29
相关资源
最近更新 更多