是否可以更改argv或是否需要创建它的调整副本?

ojb*_*ass 30 c large-data-volumes

我的应用程序可能传递了大量的参数,我希望避免将参数复制到过滤列表中的内存.我想在适当的位置过滤它们,但我很确定混淆argv数组本身,或者它指向的任何数据,可能是不可取的.有什么建议?

Mic*_*urr 68

C99标准说明了修改argv(和argc):

参数argc和argv以及argv数组指向的字符串应该可由程序修改,并在程序启动和程序终止之间保留它们最后存储的值.


Tim*_*Tim 25

一旦将argv传递给main方法,就可以像对待任何其他C数组一样对待它 - 根据需要随意更改它,只需要知道你正在做什么.除了在代码中明确使用它的内容之外,数组的内容对返回代码或程序的执行没有影响.我想不出任何理由不特别对待它是"不可取的".

当然,您仍然需要注意意外访问超出argv范围的内存.像普通C阵列一样可以访问它的另一面是,它也像任何其他正常的C阵列一样容易出现访问错误.(感谢所有在评论和其他回复中指出这一点的人!)

  • 请注意(至少在 Linux 上)您可以覆盖 `argv` 的内容以隐藏 ps 中的密码:http://unix.stackexchange.com/a/88679/27530 (2认同)

pax*_*blo 6

C标准的最新草案(N1256)规定该功能有两种允许形式main:

int main (void);
int main (int argc, char* argv[]);
Run Code Online (Sandbox Code Playgroud)

但关键是"或以其他一些实施定义的方式".在我看来,这似乎是标准的漏洞,足以驱动半挂车通过.

有些人专门"const char *"用于argv禁止更改参数.如果以这种方式定义主函数,则不允许更改argv[]指向的字符,如以下程序所示:

pax> cat qq.c
#include <stdio.h>
int main (int c, const char *v[]) {
    *v[1] = 'X';
    printf ("[%s]\n", v[1]);
    return 0;
}

pax> gcc -o qq qq.c
qq.c: In function `main':
qq.c:3: error: assignment of read-only location
Run Code Online (Sandbox Code Playgroud)

但是,如果你删除它"const",它工作正常:

pax> cat qq2.c
#include <stdio.h>
int main (int c, char *v[]) {
    *v[1] = 'X';
    printf ("[%s]\n", v[1]);
    return 0;
}

pax> gcc -o qq2 qq2.c ; ./qq2
[Xello]
Run Code Online (Sandbox Code Playgroud)

我认为这也是C++的情况.目前的草案规定:

All implementations shall allow both of the following definitions of main:
    int main();
    int main(int argc, char* argv[]);
Run Code Online (Sandbox Code Playgroud)

但它没有特别禁止其他变体,所以你可能也可以"const"在C++中接受一个版本(实际上,g ++也是如此).

您唯一需要注意的是尝试增加任何元素的大小.标准没有规定它们是如何存储的,因此扩展一个参数可能(可能会)影响其他参数或其他一些不相关的数据.