我在某处徘徊,看到了this question个.然后我开始怀疑我是否可以溢出argc.

标准要求argv[argc]必须是空指针,但如果argc溢出,这将是错误的.

(我用一个小C程序和一个python脚本来测试它,但得到了MemoryError分.)

谢谢!


Rationale for International Standard — Programming Languages — C §5.1.2.2.1 Program startup

argcargv指定为main的参数认可了广泛的先前实践.argv[argc]必须是空指针,以便为列表末尾提供冗余判断,这也是基于常见做法.

推荐答案

根据标准

所以,从你的话:

argv[argc]必须是空指针

因此,argc不能溢出,因为这样上面的说法就不成立了.

实际上

实际上,传递给程序的参数的总大小是有限的.

在我的Linux/x64系统上:

$ getconf ARG_MAX
2097152

因此,总参数大小约为2兆字节,argc不能溢出.我相信这个限制衡量的是argv中的总数据和环境的组合.如果在try 运行命令时超过此限制,exec()将失败,E2BIG将失败.从man 2 execve开始:

E2BIG  The total number of bytes in the environment (envp) and argument
       list (argv) is too large.

我相信,与其他系统相比,我的系统的~2 MB限制相对宽松.我的OS X系统报告限制为约260KB.

But what if ARG_MAX were really big?

好的,让我们假设您在一个旧的/奇怪的系统上,所以int是16位,而arg_max远远大于215,否则这是相当合理的.现在,假设您使用2个以上的15参数调用execve().该实现有两个选项.

  1. 它可以让argc个溢出...基本上,扔掉你的数据,确保你正在运行的程序以某种意想不到的、可能是错误的方式执行,并且违反了C标准.最糟糕的是,错误是无声的,所以你可能永远不会知道.

  2. 或者,它可以简单地从execve()返回EOVERFLOW,通知您它无法运行具有那么多参数的图像.现在,POSIX/SUS标准没有提到任何关于这个错误结果的内容...但是,我怀疑这仅仅是因为标准编剧从未期望ARG_MAX大于INT_MAX.

选项2是only个合理选项.如果你的系统以某种方式选择了选项#1,那么它是broken,你应该提交一份错误报告.

或者,您可以try 运行一个为16位系统编译的旧程序,但您正在通过某种仿真器或兼容层来运行它.如果您试图向程序传递超过2个15参数,我希望emulator或兼容层会给出错误消息.

C++相关问答推荐

删除逗号之间的白色字符,但不删除逗号内的内容

关于函数中返回局部指针变量的问题

使用 printf() 输出正确的小数位数?

在 C 中使用 AVX 实现矩阵运算

将所有位从最低有效位翻转到最高有效最后 1 位值的最有效方法是什么?

可能的堆栈粉碎?

&> 重定向是如何在 UNIX shell 中实现的?

K&R C 编程语言书中哈希表的有效性

OpenMP 线程 ID 如何与递归一起工作?

C 或 C++ 是否保证数组 < 数组 + SIZE?

在 Win32 上双重转换为 unsigned int 被截断为 2,147,483,648

我们可以在变量名中写注释吗?

为什么 long long 2147483647 + 1 = -2147483648?

为什么 rand() 在 Linux 上重复数字的频率远高于 Mac?

在结构数组的末尾需要空括号“{}”是什么?

如果缺少 const char* 数组初始化逗号,则生成编译器警告

在 C/C++ 中获得正模的最快方法

关于 C 中的数组初始化的困惑

为什么使用 abs() 或 fabs() 而不是条件否定?

如果不在内存中,表达式和常量存储在哪里?