【问题标题】:C - Value seems to pass to array element correctly but doesn'tC - 值似乎正确传递给数组元素但没有
【发布时间】:2018-04-27 18:10:49
【问题描述】:

抱歉,我知道这是一个措辞非常糟糕的问题 - 我只是想不出更好的表达方式。

我在这里问过这个问题,因为我似乎无法正确地用谷歌搜索找到解决方案。

代码说明:

  1. 将文件名“echo”与 file_name 字符数组分开。文件名包含“回声 x y”
  2. 循环从“x”开始,即前面的文件名长度 +1(用于空格)。
  3. while 循环循环直到看到下一个空格。 null char 是为了确保在 file_name 的结尾被击中时循环结束。
  4. 它将 file_name 的值分配给 arg_tmp,直到遇到空格,然后将此单词/字母分配给 argv 数组
  5. 然后为下一个 arg ++ current_arg 计数器

希望这是有道理的,并且那里有足够的代码来识别问题。

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'。

我已使用打印语句对其进行调试并尝试找出问题所在 - 但我似乎看不到它。

由于某种原因,它打印并传入 y 两次。

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

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

【问题讨论】:

  • 毕竟你的argv[1]argv[2]指向arg_tmp的同一个内存地址。为避免这种情况,您需要在 for 循环的每次迭代中为 arg_tmp 分配内存 malloc
  • 请发布一个完整的、可编译的和可验证的程序。片段可以去除可能成为您问题目标的错误。这种方式无法对您的问题进行任何诊断。
  • @LuisColorado 实际上,评论或回答这篇文章的 3 个人(比您早 16 小时)都根据给出的代码给了我有用的信息和答案。这导致我能够解决问题。如果我要上传一个“完整”的程序,它会长达数千行。
  • @AlexLord,这些规则是为了您的方便,它们允许我们测试您的代码而无需做额外的工作,并试图猜测您是否在编写代码 sn-p 时避风港没有消除错误。错误很难找到。事实证明(或者你不会在这里问)你有一个。您可以随心所欲地进行,但这会使我们的工作更加困难,如果不是不可能的话。而且我还没有写规则。不需要编写完整的程序......只需向您的程序添加一个 main 函数以使其可编译(并且在您发布时失败)
  • 保证您发布包含错误的代码 sn-p....

标签: c arrays


【解决方案1】:

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

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

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

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

【讨论】:

  • 所以我会做类似的事情:arg = strdup(arg_tmp); ?
  • @AlexLord 关闭:argv[current_arg] = strdup(arg_tmp)。您还需要为exec_name 执行此操作。
  • 注意:正如我现在所知道的 - 我不能使用 malloc 或 strdup(除非我为这些编写自己的函数)。这是因为我正在做一个操作系统模块课程。是否有替代方法或者我应该寻找这些的书面功能?
  • @AlexLord 即使是操作系统内核也需要不时地动态分配内存(除非它是用于最小的嵌入式系统,当内存管理需要特殊处理时)。所以希望您应该已经在内核中拥有内存管理功能?
  • @Barmar 好的。我设法找到了 malloc.c 文件,并找到了一个自定义的 strdup() 函数。所以现在它正在工作。谢谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2020-07-14
  • 2023-01-31
  • 2022-01-16
  • 2013-10-27
相关资源
最近更新 更多