如何释放一个char*(字符串),然后为它分配更多的空间?

u3r8eeie  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(263)

我正在创建一个程序,使用execvp函数执行用户输入的bash命令。在执行每个命令后,它应该接受另一个命令并执行该命令。例如:

bash$ ./prog ls -l
-rw-r--r--. 1 (info-placeholder) file1.txt

ls -l
-rw-r--r--. 1 (info-placeholder) file1.txt

为此,我需要能够将每个用户输入解析为char**,因为这是execvp函数:execvp(const char *file, char *const argv[]);
因此,我创建了这个函数来解析用户的输入,并将其放入一个动态分配的char**,称为arg_list,其中buff是程序读取的缓冲区,bytesread函数读取的字节数。

void parse_input(char **arg_list, char *buff, int bytes) {
    char *word = malloc(128);
    int num_spaces = 0;
    for (int i = 0; i < bytes; i++) {
        if (buff[i] == ' ') {
            num_spaces++;
        } // if
    } // for
    arg_list = malloc((num_spaces) * sizeof(char *));
    for (int i = 0, j = 0; i < bytes; i++) {
        if (buff[i] != ' ' && buff[i] != (char) 0) {
            word[i] = buff[i];
        } else {
            word[i] = '\0';
            arg_list[j] = word;
            j++;
            free(word);
            word = malloc(128);
        } // else
    } // for
    free(word);
} // parse_input

ls -l作为用户输入进行测试后,发现word在添加到arg_list后没有被重置。我不确定还可以如何将用户输入的单词添加到列表中,以及为什么word没有被重置。
编辑:我现在意识到我的代码中有多少错误,而且可能还有更多的错误,对不起。为了简短起见,我已经尝试根据你们的更正来修复我的代码,但我仍然不能让它工作。下面是:

void pars_input(char ***arg_list, char *buff, int bytes) {
    printf("Beginning to parse user input\n");
    int num_spaces = 0;
    bool is_white_space = true;
    for (int i = 0; i < bytes; i++) {
        if (is_white_space && !isspace(buff[i])) {
            num_spaces++;
            is_white_space = false;
        } else if (!is_white_space && isspace(buff[i])) {
            is_white_space = true;
        } // else if
    } // for
    printf("Number of words: %d\n", num_spaces);

    (*arg_list) = malloc((num_spaces + 1) * sizeof(char *));
    is_white_space = true;
    for (int i = 0, j = 0, k = 0; i < bytes; i++) {
        if (is_white_space && !isspace(buff[j])) {
            (*arg_list)[j][k] = '\0';
            printf("Word added: %s\n", (*arg_list)[j]);
            j++;
            k = 0;
        } // if
        else if (!is_white_space && isspace(buff[i])) {
            is_white_space = true;
            (*arg_list)[j][k] = buff[i];
            k++;
        } // else if
    } // for
} // parse_input

如果没有一个临时单词来添加buff中的字符,我就无法知道如何将该单词添加到动态分配的arg_list中。

dvtswwa3

dvtswwa31#

问题很多。

  • 你不想释放word指向的内存。它也被arg_list[ j ]指向,你仍然在使用它。删除第一个free(word);
  • 最后一个单词没有以空格结尾,所以它不会被添加到arg_list中。
  • word[i] = buff[i];显然对除第一个单词以外的任何单词都是错误的。如果输入以空格开头,它对第一个单词也是错误的。
  • 您分配了num_spaces元素,但可能还有一个以上的元素。例如,a b c有两个空格,但有三个单词。
  • 您不处理前导空格。
  • 您不能处理一行中的多个空格。
  • 例如,您只将空格视为单词分隔符,不包括制表符。
  • 您将arg_list作为参数,但在未使用它的情况下替换了它的值。
  • 你不把列表返回给调用者,改变arg_list对调用者没有影响,因为C是按值传递的。
  • 返回arg_list给调用者是不够的。调用者还需要知道数组中有多少个元素。例如,这可以通过添加一个额外的元素NULL来实现,就像exec*所期望的那样。

相关问题