C - 值似乎正确地传递给数组元素,但没有

时间:2017-11-14 17:25:48

标签: c arrays

对不起,我知道这是一个措辞严厉的问题 - 我想不出更好的说法。

我在这里问过这个问题,因为我无法正确地说出来找到解决方案我的谷歌搜索。

代码说明:

  1. 从file_name char数组中分隔文件名'echo'。 file_name包含'echo x y'
  2. 循环从'x'开始,这是先前的文件名长度+1(对于空格)。
  3. while循环循环直到看到下一个空格。 null char用于确保在命令file_name结束时循环结束。
  4. 它将file_name的值分配给arg_tmp,直到它命中空格然后将此单词/字母分配给argv数组
  5. 然后++下一个arg的current_arg计数器
  6. 希望这是有道理的,并且有足够的代码来识别问题。

    MAX_FILE_NAME_LENGTH为14

    strlen(exec_name)= 4所以+1使它成为5。

    长度为9。

    这是我的代码:

    void
     setup_argv(const char *file_name, char *argv[], size_t argc, size_t length)
     {
       char exec_name[MAX_FILE_NAME_LENGTH];
       char arg_tmp[MAX_FILE_NAME_LENGTH]; // temp arg holder
       // get file name
       get_exec_name(file_name, exec_name);
       // add file name to argv
       argv[0] = exec_name;
    
       // get rest of args
       // +1 - start at first character of next arg
       int current_arg=1;
       for(size_t i = strlen(exec_name)+1; i < length; i++)
       {
         size_t j = 0;
         while(!(file_name[i] == NULL_CHAR || file_name[i] == SPACE))
         {
           arg_tmp[j] = file_name[i];
           printf("::WHILE::%s\n", arg_tmp);
           i++;
         }
         printf("::BOTH::%d %s\n", current_arg, arg_tmp);
         arg_tmp[++j] = NULL_CHAR;
         argv[current_arg] = arg_tmp;
         printf("::ARGV CUR ARG::%s\n", argv[current_arg]);
         printf("::ARGV::%s\n", argv[1]);
         printf("::CUR ARG::%d\n", current_arg);
         current_arg++;
         printf("::CUR ARG::%d\n", current_arg);
       }
    
       printf("::ARGV ALL::%s %s %s\n", argv[0], argv[1], argv[2]);
     }
    

    这是我的输出:

    ::WHILE::x
    ::BOTH::1 x
    ::ARGV CUR ARG::x
    ::ARGV::x
    ::CUR ARG::1
    ::CUR ARG::2
    ::WHILE::y
    ::BOTH::2 y
    ::ARGV CUR ARG::y
    ::ARGV::y
    ::CUR ARG::2
    ::CUR ARG::3
    ::ARGV ALL::echo y y
    

    最后一行应该打印的是'echo x y'。

    我已经使用print语句来调试它并尝试找出它出错的地方 - 但我似乎无法看到它。

    由于某种原因,它打印并传递了两次。

    这是为什么?我做错了什么?

    编辑:正如我现在想的那样 - 我不能使用malloc或strdup(除非我为这些编写自己的函数)。这是因为我正在做一个操作系统模块课程。有替代方法还是我应该寻找这些方法的书面功能?

1 个答案:

答案 0 :(得分:4)

变量argv是一个指针数组,你将循环中的所有指针指向同一个地方,即arg_temp的第一个元素。

这比你想象的还要糟糕,因为当setup_argv返回时,arg_temp的生命周期结束并且它不再存在,留下一系列迷路和无效指针。试图取消引用它们将导致undefined behavior

作为一种解决方案,我建议你使用普通的strdup函数,或者编写自己的字符串复制函数,为字符串分配新的内存。

最后,对于正确的argv样式数组,应该使用空指针终止它。