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

use*_*869 2 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 < 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]);
    }
}
Run Code Online (Sandbox Code Playgroud)

出来的是:

what, what
test, test
again, again
wow, wow
____________
pK@??
test
again
wow
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会这样吗?谢谢

unw*_*ind 7

这个:

char ** file_names = malloc(10);
Run Code Online (Sandbox Code Playgroud)

是个bug.它试图分配10个字节,这与你需要多少字节完全没有关系.分配不足然后覆盖会给你带来未定义的行为.

它应该是这样的:

char **file_names = malloc(argc * sizeof *file_names);
Run Code Online (Sandbox Code Playgroud)

这通过乘以参数的数量来计算分配的大小(argc如果你不想存储,argv[0]那么这(argc - 1)当然应该是字符指针的大小),表示为sizeof *file_names.既然file_names是类型char * *,类型*file_nameschar *,这是你想要的.这是一般模式,可以经常应用,它可以让您停止重复类型名称.它可以保护您免受错误.

例如比较:

double *floats = malloc(1024 * sizeof(float));  /* BAD CODE */
Run Code Online (Sandbox Code Playgroud)

和:

double *floats = malloc(1024 * sizeof *floats);
Run Code Online (Sandbox Code Playgroud)

如果你想象它最初是float *floats(正如命名所示)那么第一个变体包含另一个分配不足的bug,而第二个变种"幸存"类型的变化而没有错误.

然后你需要在假设它之前检查它是否成功.