【问题标题】:Why does my program crash if I don't give command line arguments to it? [closed]如果我不给它提供命令行参数,为什么我的程序会崩溃? [关闭]
【发布时间】:2013-01-02 12:00:00
【问题描述】:

我制作了一个简单的测试程序来玩转 C++11 线程。

#include <iostream>
#include <stdlib.h>
#include <thread>
using namespace std;

void tee(int civ)
{
    for(int loop=0; loop<19; loop++, civ++)
    {
        civ = civ%19;
        cout << loop << "\t" << civ << endl;
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

void koot()
{
    while(true)
    {
        cout << ":) ";
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

int main(int argc, char *argv[])
{
    thread saie(tee, atoi(argv[1])),
        kamaa(koot);
    saie.join();
    kamaa.join();

    return 0;
}

只要我提供命令行参数,它就可以正常工作,但如果我不提供,它就会崩溃。 如何解决? 我尝试检查参数计数,如果它们存在,则无济于事。

编辑:我必须添加这一行:

if(argc < 2) return 1;

【问题讨论】:

  • 您正在使用agv[1],如果没有给出命令行参数,它将是NULL。你是怎么检查的?
  • 因为argv[1] 将是NULL
  • 嗯...因为您在调用saie 时使用了argv[1],如果您不提供它就是NULL?
  • 为什么会是NULL,伙计们?在我看来,它的值,例如它,将是完全未指定的,并且尝试访问它会调用未定义的行为。
  • 好的,因为[C++11: 3.6.1/2] 说:The value of argv[argc] shall be 0.。那么请注意,OP,这并不意味着argv[2] 等也将是NULL

标签: c++ command-line crash command-line-arguments


【解决方案1】:

因为您正在访问它而崩溃

argv[1]

如果有的话,它将保存一个命令行参数(程序名除外)。你应该检查argc是否大于1。为什么大于1?因为第一个命令行参数是程序本身的名称。所以argc 总是大于0。索引从0 开始。所以如果argc == 1,只有argv[0]是有效的。

#include <iostream>
int main(int argc, char* argv[])
{
  // no need to check argc for argv[0]
  std::cout << argc << " " << argv[0] << "\n";
}

【讨论】:

  • 谢谢!显然我需要这个: if(argc
【解决方案2】:

argv[1] 为 null,导致对 atoi() 的调用崩溃。请注意,C++ 中的数组索引是从零开始的!

【讨论】:

    【解决方案3】:

    因为你没有检查argc &gt; 1 并且你尝试访问argv[1]

    解决这个问题的方法是首先检查argc &gt; 1,然后访问argv[1]。

    int main(int argc, char *argv[])
    {
    
        if(argc > 1){
        thread saie(tee, atoi(argv[1])),
            kamaa(koot);
        saie.join();
        kamaa.join();
       }
        return 0;
    }
    

    要记住的要点:

    1. argc 默认为 1。这是保存编号的参数计数器。传递给程序的参数。默认情况下,它为 1,因为程序获取可执行文件的名称(和路径)

    2. argv 保存以 NULL 结尾的字符数组(或字符串)的数组。 argv[0] 将始终包含可执行文件的名称。

    3. 永远不要假设用户总是会输入参数。并且在将来访问argv 或任何数组时始终进行边界检查。

    【讨论】:

      【解决方案4】:

      试试下面的代码:

      int main(int argc, char *argv[])
      {
          if(argc < 2) {   cout<<"No command line arguments found\n Aborting!\n"; return 1;}
          else         {   thread saie(tee, atoi(argv[1])),kamaa(koot);}
          saie.join();
          kamaa.join();
      
          return 0;
      }
      

      您正在尝试访问不存在的命令行参数 argv[1]。检查命令行参数是否存在总是更好。

      【讨论】:

      • argc 总是等于或大于 1
      • typo.. 应该是 argc
      猜你喜欢
      • 2013-04-06
      • 2023-04-06
      • 1970-01-01
      • 2016-05-09
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      相关资源
      最近更新 更多