【问题标题】:Mutating array of char* using a function but string values change after function exit.使用函数改变 char* 数组,但字符串值在函数退出后发生变化。
【发布时间】:2015-12-15 14:31:03
【问题描述】:

我正在构建一个简单的命令行解释器。 它从标准输入读取用户输入并对其进行解析以在单独的子进程中运行程序。

用户输入将采用以下格式:... arg1 到 arg4 是可能的命令行参数。

(我是约束输入格式,路径

目前 main() 函数只读取一行用户输入。

我的问题是,我将输入解析和存储抽象为一个名为 extractArgs(char**,char*) 的函数。 此函数解析输入并提取 execv(char* argc, char* argv[]) 参数所需的数据。

它肯定会正确解析输入。我将调试打印语句放在 main 和 extractArgs 中以打印出 argv 数组中的字符串。 extractArgs 中的那个显示 argv 持有正确的值,但 main 中的那个打印废话。

我怀疑这与 extractArgs 完成执行后内存被回收有关,因此当旧值被覆盖时,argv 指针最终指向废话..

这是正确的吗?我能做些什么来阻止它?我必须使用malloc吗?有没有办法简单地保持argv数组中的指针不被回收?

// argv is the char* array to store cmd args from stdin for execv, 
// path is string to store path from user input
int extractArgs(char** argv, char* path)
{
    const char* fmessageNotFound = "%s not found\n";
    struct stat buf;

    const char delim[2] = " ";
    char argStr[90];
    char* token;
    int i;

    scanf("%s", path); // get path

    // handle invalid program path
    if (stat(path, &buf) == -1) 
    {
        printf(fmessageNotFound, path);
        return -1;
    }

    argv[0] = path; // argv[0] must be program name
    argv[1] = NULL; // set terminating element for 0 argument case.

    // read all cmd line args.
    // constraints: up to 4 args, arg lengths <20 chars
    fgets(argStr, 90, stdin);
    argStr[strcspn(argStr, "\n")] = '\0'; // clear trailing \n

    // populate argv array
    token = strtok(argStr, " ");
    for (i = 1; i < 5 && token != NULL; i++)
    {
        argv[i] = token;
        token = strtok(NULL, " ");
    }
    // set terminating element after populating argv
    argv[i] = NULL;

    // test and print all the arguments
    i = 0;
    while (argv[i] != NULL) {

        // EVERYTHING WORKS HERE
        printf("%s\n", argv[i]);
        i++;
    }

    return 0;
}

int main()
{
    pid_t chpid;
    char* argv[6];  // max 4 cmd args + name + NULL terminator
    char path[100]; // command path length <100

    if (extractArgs(argv, path) == -1) // invalid path
    {
        fgets(path, 100, stdin); // clean up newline
        return;
    }

    // Print values in argv
    int i = 0;
    while (argv[i] != NULL) {

        // PRINTS NONSENSE.
        printf("%s\n", argv[i]);
        i++;
    }

    chpid = fork();
    if (chpid == 0)
    {
        execv(path, argv);
    }
    wait(NULL);
    return 0;
}

【问题讨论】:

  • argv[i] = token; 似乎您正在将返回的指针之一设置为指向局部变量。 argv 的所有成员必须设置为指向 null 或函数退出后有效的内存位置。

标签: c pointers multidimensional-array scope argv


【解决方案1】:

extractArgs 函数中,将指向本地数组argStr 的指针存储在argv 数组中。

一旦函数返回,这些指针就不再有效,因为argStr 已经超出范围。当您尝试使用argv 数组中的杂散指针时,这会导致未定义的行为

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-06
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多