困惑为什么通过引用传递char **没有按预期工作

时间:2015-07-21 03:29:13

标签: c pass-by-reference

我正在重新学习C并编写一小段测试代码,同时通过引用查看传递:

#include <stdio.h>
#include <string.h>

void distort_flags_list(char*** flags);

int NUM_FLAGS = 2;

int main(int argc, char** argv)
{
    distort_flags_list(&argv);

    for (int flag_offset = 0; flag_offset < NUM_FLAGS; flag_offset++) {
        printf("%s\n", *(argv + flag_offset));
    }

    return 0;
}

void distort_flags_list(char*** flags)
{
    char* tester[2] = {"first", "second"};
    *flags = tester;
}

我很好奇为什么在运行时,我得到以下输出:

first
(null)
而不是打印“第一”和“第二”。根据我的理解,当将指针传递给argvdistort_flags_list时,您正在更改指针指向该函数中定义的tester地址的位置。

为什么会发生这种情况的任何解释?

2 个答案:

答案 0 :(得分:2)

在函数distort_flags_list中,您将*flags的值设置为函数返回后无效的值。

在调用argv后访问distort_flags_list中的任何内容是未定义的行为。

为确保函数返回后值*flags继续有效,您需要使用动态内存分配。

void distort_flags_list(char*** flags)
{
    *flags = malloc(2*sizeof(**flags));
    (*flags)[0] = malloc(20); // Make is large enough
    (*flags)[1] = malloc(20); //  ditto
    strcpy((*flags)[0], "first");
    strcpy((*flags)[1], "second");
}

然后,添加代码以在main中释放内存。

int main(int argc, char** argv)
{
    distort_flags_list(&argv);

    for (int flag_offset = 0; flag_offset < NUM_FLAGS; flag_offset++) {
        printf("%s\n", *(argv + flag_offset));
    }

    free(argv[1]);
    free(argv[0]);
    free(argv);

    return 0;
}

答案 1 :(得分:2)

不能在功能块之外使用局部变量。您可以使用上述方法,也可以使用关键字static

static char* tester[2] = {"first", "second"};

这样tester保持其值直到程序结束。

在此处查看演示 - https://ideone.com/eLDn3m