为啥命令行参数在访问时会产生分段错误?

Posted

技术标签:

【中文标题】为啥命令行参数在访问时会产生分段错误?【英文标题】:Why do command line arguments generate segmentation fault when accessed?为什么命令行参数在访问时会产生分段错误? 【发布时间】:2021-03-06 15:09:29 【问题描述】:

我在尝试逐字符读取命令行参数时遇到分段错误。

我有以下代码:

int main(int argc, char** argv)

int i,j;
    for(i=1;i<argc;i++)
    
        for(j=0;argv[i][j]!=0;j++)
        
             printf("%c",argv[i][j]);
        
        //printf("%c",argv[i][0]);
    

此代码运行,但是当我取消注释 printf("%c",argv[i][0]); 行时,我得到一个分段错误。 为什么这被认为是对未分配内存的访问,我应该如何在不检查其内容的情况下解析命令行参数?

具体来说,我想知道参数是否为以下形式:e 表示加号或减号,后跟“e”,后跟一个十六进制数字。在 c 中如何处理这个问题?

【问题讨论】:

请不要在给出一些(有效的!)答案后更改您询问的代码。这样,您就可以使这些答案变得无关紧要甚至是错误的。如果您想通过提供新的但仍无法工作的代码版本来增强您的问题或缩小问题范围,请将其添加到原始版本的下方或发布一个新问题。 明白。我还是这个平台的新手,还在学习如何使用它。 【参考方案1】:

你的内循环条件不正确:

argv[i][j]!="\0"

您正在将单个字符与字符串常量进行比较。该字符串常量衰减到它存储的地址,这是实际与参数字符串的元素进行比较的地址。结果,因为您没有正确检查终止的空字节,所以您读到了字符串的末尾。这样做会触发undefined behavior,在您的情况下,这会导致您的代码有时会崩溃,有时不会。

你想要在这里检查值 0:

argv[i][j]!=0

【讨论】:

在问题中注明和编辑,但这并不能回答我的问题。问题是注释行不会运行。我需要一种方法来解析参数。 @MegaFlipFlop 一旦你修复了它就会运行。你试过了吗?如果是这样,您得到的结果与您的预期有什么不同?

以上是关于为啥命令行参数在访问时会产生分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在将命令行图像文件中的参数作为参数传递时出现错误

当我们不传递任何命令行参数时,为啥我们不会得到错误?

为啥从命令行编译而不是从 IDE 编译时会出现歧义错误?

操作系统在哪里存储命令行参数?

为啥 9 之后的 bash 命令行参数需要大括号?

为啥在传递引用的参数时会得到“/bin/sh:参数列表太长”?