传递argv指针至handleInput后读取argv[1]触发Segmentation Fault 11
问题描述
在将argv以引用方式传入handleInput函数后,读取argv[1]触发Segmentation Fault 11,但在main函数中读取正常。已知argc显示有两个参数,且handleInput中能正常读取argv[0],却无法读取argv[1]。
相关代码:
#include <stdio.h> void handleInput(int *argc, char ***argv) { printf("%d\n", *argc); printf("%s\n", *argv[0]); printf("%s\n", *argv[1]); printf("\n"); } int main(int argc, char **argv) { printf("%d\n", argc); printf("%s\n", argv[0]); printf("%s\n", argv[1]); printf("\n"); handleInput(&argc, &argv); return 0; }
运行命令:
$ ./segfault parameter
运行结果:
2 ./segfault parameter 2 ./segfault Segmentation fault: 11
编译器信息:
$ clang -v Apple clang version 14.0.0 (clang-1400.0.29.102) Target: arm64-apple-darwin22.1.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin
错误原因及解决方法
错误核心是运算符优先级问题:
在C语言中,数组下标运算符[]的优先级高于间接寻址运算符*。*argv[1]会被编译器解释为*(argv[1]),而非预期的(*argv)[1]。
argv是char***类型,argv[1]会取这个指针的第2个元素(即&argv指向地址的下一个内存位置),这部分属于未分配的垃圾内存,解引用后直接触发段错误。*argv[0]能正常工作是因为argv[0]等价于&argv本身,解引用后得到原main函数中的char**类型argv,对应程序路径字符串的指针,因此可以正常打印。
修正方法是给*argv添加括号,明确先解引用得到原char**类型的argv,再进行下标访问:
修正后的handleInput函数:
void handleInput(int *argc, char ***argv) { printf("%d\n", *argc); printf("%s\n", (*argv)[0]); printf("%s\n", (*argv)[1]); printf("\n"); }
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

