【问题标题】:Getopt error: memory protection violationGetopt 错误:内存保护违规
【发布时间】:2019-04-08 18:35:35
【问题描述】:

我尝试使用getopt,但我遇到了问题。 运行./a.out -A -R 后,我看到了 memory protection violation。 我做错了什么?

int c;
int rec_flag=0;
int copy_range=0;
while((c=getopt(argc,argv,"AR:"))!=-1){
    switch(c){
        case 'A':
            copy_range=1;
            break;
        case 'R':
            rec_flag=1;
            break;
        case '?':
            if (optopt == 'c')
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf (stderr,"Unknown option character `\\x%x'.\n",optopt);
            return 1;
        default:
            abort ();
    }
}

【问题讨论】:

  • 这不是minimal reproducible example。您是否尝试过通过调试器运行代码?
  • 我的程序需要 2 个参数(目录路径)和 -A 等可选选项。我尝试“./a.out /home /bin -A”,但这不起作用
  • 问题在于getopt 格式字符串:c=getopt(argc,argv,"AR:") : 表示R 选项需要一个参数。你没有提供任何东西。这不应该崩溃,因为传递的参数数量是正确的。
  • -R name 选项被识别时,您将丢弃optarg 中的值。从字符串"AR:" 中删除R 之后的冒号,或者将optarg 的值存储在某处以保存提供的名称。您确定崩溃是在getopt() 中而不是在一些后续代码中吗? getopt() 的标准版本不应仅仅因为命令被错误地调用而没有与冒号匹配的参数而崩溃。
  • 我猜这是处理参数的任何函数,您将参数传递给函数是错误的。通常getopt代码直接在main中处理,系统不会错误传入参数。但是,如果您指定的 argcargv 实际包含的更大,您可能会遇到运行时错误。

标签: c linux getopt


【解决方案1】:
while((c=getopt(argc,argv,"AR:"))!=-1){
 switch(c){
    ...
    case '?':  if (optopt == 'c')
                   fprintf (stderr, "Option -%c requires an argument.\n", optopt);

getopt 永远不会在您的程序中将optopt 设置为“c”。

在您粘贴的示例代码中,格式字符串为“abc:”。因此,如果 -c 不带参数传递,optopt 将是“c”(如上所述,格式字符串中的冒号表示它需要)。您的程序根本没有选项-c。 您没有删除第三个选项规范,因为您的程序接受 2 个参数...对吗?

确保您像上面所说的那样 #included <unistd.h><ctype.h>,然后尝试将 getopt 变量声明为 externMemory protection violation 可能意味着链接器当前将它们作为传递包含,但内核不希望您的进程访问 libc 的一部分映射到的共享内存区域。只是一个猜测,但它确实清除了我在尝试运行您的代码时遇到的一些不当行为。

https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt

【讨论】:

    猜你喜欢
    • 2021-07-18
    • 2023-03-08
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 2015-11-14
    • 2013-08-10
    • 2016-10-13
    • 1970-01-01
    相关资源
    最近更新 更多