C语言中的内存管理命令行参数

C语言中的内存管理命令行参数,c,command-line-arguments,C,Command Line Arguments,我正在编写一个简单的程序,它接受命令行参数并将它们存储到char**。我正试图学习更多关于内存管理的知识,但无法克服这个简单的障碍。我的程序应该将命令行argumetns复制到动态分配的char**。然而,我阵法中的第一个位置总是腐蚀者。下面是代码及其打印内容: if (strcmp(argv[1], "test") ==0) { test(); } else { char ** file_names = malloc(10); for(int i =0; i <

我正在编写一个简单的程序,它接受命令行参数并将它们存储到char**。我正试图学习更多关于内存管理的知识,但无法克服这个简单的障碍。我的程序应该将命令行argumetns复制到动态分配的char**。然而,我阵法中的第一个位置总是腐蚀者。下面是代码及其打印内容:

if (strcmp(argv[1], "test") ==0)
{
    test();
}
else
{
    char ** file_names = malloc(10);

    for(int i =0; i < argc-1; ++i)
    {
        file_names[i] = malloc(10);
        strcpy(file_names[i], argv[i+1]);

        printf("%s, %s\n", argv[i+1], file_names[i]);
    }

    printf("____________\n");

    for(int i =0; i < argc-1; ++i)
    {
        printf("%s\n", file_names[i]);
    }
}
有人能解释一下为什么会这样吗?谢谢

这:

char ** file_names = malloc(10);
这是一只虫子。它试图分配10个字节,这与需要多少字节无关。分配不足然后覆盖会导致未定义的行为

应该是这样的:

char **file_names = malloc(argc * sizeof *file_names);
这是通过将参数的数量(
argc
)乘以分配的大小来计算的,如果您不想存储
argv[0]
,那么这应该是
(argc-1)
,当然)乘以字符指针的大小,该指针表示为
sizeof*file\u names
。由于
文件名
的类型为
char**
,因此
*文件名
的类型为
char*
,这正是您想要的。这是一种通用模式,可以经常应用,并且可以让您停止重复类型名称。它可以保护你不犯错误

例如,比较:

double *floats = malloc(1024 * sizeof(float));  /* BAD CODE */
以及:

如果您想象它最初是
float*floats
(如命名所示),那么第一个变体包含另一个分配不足的bug,而第二个变体在类型更改后“幸存”下来,没有出现错误


然后,在假设它成功之前,您需要检查它是否成功。

您希望为
文件名分配适当的内存量,可能更像:

char ** file_names = malloc(sizeof(char*) * (argc - 1));

您很可能有未定义的行为,对于
文件名
您只分配了十个字节,而不是十个指针的空间。您能解释一下如何分配字节吗。我明白你的意思,只是不明白答案。只需参考答案部分谢谢。从不知道分配不足和覆盖不足。你能解释一下你在用第二行做什么吗。“malloc(argc*sizeof*file_names)”有什么作用?@user2455869:它为argc元素分配内存,其大小与
*file_names
的大小相同,即
sizeof(char*)
@user2455869您认为
malloc(10)
是什么意思?当然,如果您使用的比分配的多,这可能是个问题,这是理所当然的。但是如果您想复制所有参数,请使用
(sizeof(char*)*argc)
。@WeatherVane这是根据
for
循环来计算不需要的可执行文件名。但是如果是这样的话,那么使用
argc
而不是
argc-1
啊,是的,我错过了他的
argv[I+1]
double *floats = malloc(1024 * sizeof *floats);
char ** file_names = malloc(sizeof(char*) * (argc - 1));