错误"恐慌:尝试复制释放的标量"使用Getopt :: Long时

时间:2014-10-22 13:42:37

标签: perl

我收到错误:

panic: attempt to copy freed scalar a121fb4 to a156be8 at ./p.pl line 13.

当我运行以下程序(p.pl)时:

use warnings;
use strict;
use Getopt::Long qw(GetOptions);

main(@ARGV);

sub main {
  GetOptions ();

  print "\@ARGV=@ARGV\n";
  my $arg=shift;
}

使用一个或多个命令行参数时,例如p.pl 1会出错。

这是什么原因?

2 个答案:

答案 0 :(得分:4)

发生错误是因为您正在通过@ARGV

@_设置为@ARGV值的别名。 GetOptions然后对原始@ARGV执行操作,因此您的后期shift @_会出现问题。

以下是两种解决方案。

  1. 在调用sub:

    之前执行GetOptions
    GetOptions();  # Manipulate @ARGV before passing it.
    
    main(@ARGV);
    
    sub main {
        print "\@ARGV=@ARGV\n";
        my $arg = shift;
    }
    
  2. 不要过分@ARGV,因为它无论如何都是全球性的:

    main();   # Don't pass @ARGV since it's global
    
    sub main {
        GetOptions();
    
        print "\@ARGV=@ARGV\n";
        my $arg = shift @ARGV;
    }
    

答案 1 :(得分:0)

我相信我刚刚发送的详细信息是"错误规避请求"到Getopt :: Long 将有助于澄清这种情况:

https://rt.cpan.org/Ticket/Display.html?id=120562

这对触发器很敏感:没有"我的$ a"虫子不再出现了。

Post Scriptum:我认识到Getopt :: Long在其文档中多次提及@ARGV,并且在成功返回GetOptions()"时,#34; @ARGV等备注将始终为空。 A"临时"绕过解决方案可能是Getopt :: Long警告这个核心Perl bug,程序员应该使用类似Getopt :: Long :: GetOptionsFromArray([@ ARGV])的东西,如果他们希望能够在使用之后使用@ARGV Getopt ::长期使用。