我当时正徘徊在SO中,看到了这个问题。然后我开始怀疑我是否可以溢出argc。
标准说argv[argc]
必须是一个空指针,但是如果argc溢出,它将为假。
(我写了一个小的C程序和一个python脚本对其进行测试,但得到了一个MemoryError
。)
谢谢!
国际标准的理由-编程语言-C§5.1.2.2.1程序启动
的规范
argc
和argv
作为main
广泛认可的先验实践的论据。argv[argc]
也是根据惯例,必须为空指针,以提供对列表末尾的冗余检查。
我当时正徘徊在SO中,看到了这个问题。然后我开始怀疑我是否可以溢出argc。
标准说argv[argc]
必须是一个空指针,但是如果argc溢出,它将为假。
(我写了一个小的C程序和一个python脚本对其进行测试,但得到了一个MemoryError
。)
谢谢!
国际标准的理由-编程语言-C§5.1.2.2.1程序启动
的规范
argc
和argv
作为main
广泛认可的先验实践的论据。argv[argc]
也是根据惯例,必须为空指针,以提供对列表末尾的冗余检查。
main
由execve
-安装的-的初始堆栈(包括其参数(即argv
))要受限制得多(通常为几兆字节)。所以argc
不到几个milions,我从来没有听说过的OS的地方argc
可能是近INT_MAX
argc
应该有type size_t
。
Answers:
因此,从您的报价:
argv[argc]
必须为空指针
因此,argc
不能溢出,因为这样上面的语句将不成立。
实际上,传递给程序的参数的总大小是有限的。
在我的Linux / x64系统上:
$ getconf ARG_MAX 2097152
因此,总参数大小约为2兆字节,并且argc
不会溢出。我认为此限制衡量的argv
是环境中总数据的组合。如果您在尝试运行命令时超过此限制,exec()
将失败E2BIG
。来自man 2 execve
:
E2BIG环境(envp)和参数中的字节总数 列表(argv)太大。
我相信,与其他系统相比,我的系统上约2兆字节的限制相对宽松。我的OS X系统报告限制为260KB。
ARG_MAX
真的很大呢?好的,假设您使用的是旧/古怪的系统,那么int
16位也是如此,并且ARG_MAX远远超过2 15,这在其他方面还是很合理的。现在,假设您execve()
使用2个以上的15个参数进行调用。该实现有两个选择。
它可能会导致argc
溢出...基本上是,丢弃数据,确保正在运行的程序以某种意外且可能错误的方式执行,并且违反了C标准。最糟糕的是,该错误是无声的,因此您可能永远都不知道。
或者,它可以简单地EOVERFLOW
从返回execve()
,通知您它根本无法运行具有这么多参数的映像。现在,POSIX / SUS标准没有提及任何有关此错误结果的信息……但是,我怀疑这仅仅是因为标准编写者从未期望ARG_MAX
过大于INT_MAX
。
选项#2是唯一合理的选项。如果您的系统以某种方式选择了选项#1,则该选项已损坏,您应该提交错误报告。
另外,您可能试图运行为16位系统编译的旧程序,但正在通过某种仿真器或兼容性层运行它。如果您尝试将2 15个以上的参数传递给程序,我希望模拟器或兼容性层会给出错误消息。
argv[argc]
空指针意味着需要设置ARG_MAX
足够小的值而argc
不会溢出。
实际上,不可以。大多数系统上放置的总大小相对较低的限制argv
和envp
。数十KB到数百KB的限制并不罕见。请参阅http://www.in-ulm.de/~mascheck/various/argmax/,以合理全面地列出各种OS的限制。
我尝试了这个:
test.c:
⚡⚡⚡ more test.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("argc = %d\n", argc);
printf("Size of argc = %d\n", sizeof(argc));
return 0;
}
然后用了一个大的zipfile
⚡⚡⚡ ls -h bigfile
-rw-r--r-- 1 ehwas ehwas 355M Jan 22 16:54 bigfile
然后将文件作为测试程序的参数读取:
⚡⚡⚡ ./test $(more bigfile)
结果:
5 minutes nothing happend, then everything froze
然后我尝试了一个较小的文件:
⚡⚡⚡ ls -h notsobigfile
-rw-r--r-- 1 ehwas ehwas 6.7M Jan 22 17:04 notsobigfile
和:
⚡⚡⚡ ./test $(more notsobigfile)
bash: ./test: Argument list too long
如标准所示,argv [argc]必须为有效值。
因此,如果运行时环境处于无法保证的状况,则不应启动程序。
Standard says that argv[argc] must be a null pointer but this will be false if argc overflow
-我读成“不要让argc溢出”。(“医生,当我这样做时会很痛”)