简体   繁体   English

strcmp()的分段错误

[英]Segmentation fault with strcmp()

if(strcmp(argv[2], NULL) == 0)

I'm passing 3 command line arguments but I also want to run it with only 2 command line arguments with the above statement. 我传递了3个命令行参数,但我也想用上面的语句只用2个命令行参数来运行它。 But a segmentation fault error is being displayed. 但是正在显示分段错误错误。

I also tried with 我也尝试过

if(argc < 3)

but it also didn't work...same segmentation fault... 但它也没有用......同样的分段错误......

Why segmentation fault? 为什么分段错误?

Because of code if(strcmp(argv[2], NULL) == 0) , you are passing NULL as string pointer to strcmp() function; 由于代码if(strcmp(argv[2], NULL) == 0) ,你将NULL作为字符串指针传递给strcmp()函数; that try to deference at NULL to compare chars codes (eg acsii code) this cause undefined behavior at run time. 尝试在NULL处进行deference以比较字符代码(例如acsii代码),这会在运行时导致未定义的行为。

You should compare a string pointer with NULL using == as if(argv[2] == NULL) 您应该使用==将字符串指针与NULL进行比较, if(argv[2] == NULL)

I'm passing 3 command line arguments but I also want to run it with only 2 command line arguments with the above statement. 我传递了3个命令行参数,但我也想用上面的语句只用2个命令行参数来运行它。

You can implement this in two ways: 您可以通过两种方式实现此目的:

  1. The main syntax is: 主要语法是:

     int main(int argc, char* argv[]) 

    The first argument argc is argument counter that is total number of arguments passed to your process including process name. 第一个参数argc是参数计数器,它是传递给您的进程的参数总数,包括进程名称。

    So when you pass no extra argument then argc == 1 eg ./exe 所以当你没有传递额外的参数时, argc == 1例如./exe

    Suppose if you pass three arguments as follows: 假设您传递三个参数如下:

     ./exe firstname lastname 

    Then argc == 3 , it looks like you are passing two arguments but including executable name you are actually passing three arguments to process. 然后argc == 3 ,看起来你传递了两个参数,但是包含可执行文件名,你实际上是要传递三个参数进行处理。

    So you can use of argc value to iterate in a loop to print arguments passed (other then executable) 所以你可以使用argc值来循环迭代来打印传递的参数(其他可执行文件)

      printf("Process name is: %s", argv[0]); for(i = 1; i < argc; i++ ){ printf("argv[%d] %s\\n", argv[i]); } 
  2. Second technique is using second argument: argv[] is NULL terminated array of string strings so argv[argc] is always equals to NULL. 第二种技术是使用第二个参数: argv[]是字符串字符串的NULL终止数组,因此argv[argc]始终等于NULL。 You can use this information in loop to iterate and process of arguments passed. 您可以在循环中使用此信息来迭代和处理传递的参数。

    To understand this suppose you are executing function as: 要理解这一点,假设您正在执行以下功能:

     ./exe firstname lastname 

    then argv[0] == ./exe , argv[1] == firstname and argv[2] == lastname and argv[3] == NULL , Note this time argc == 3 ( argv[argc] means argv[3] == NULL). 然后argv[0] == ./exe argv[1] == firstnameargv[2] == lastnameargv[3] == NULL ,注意这次argc == 3argv[argc]表示argv[3] == NULL)。

    For example to print all arguments, you can write you code like: 例如,要打印所有参数,您可以编写如下代码:

      int i = 1; printf("Process name is: %s", argv[0]); while(argv[i]){// terminates when argv[i] == NULL printf("argv[%d] %s\\n", argv[i]); i++; } 

Do you notice argv[0] is always your executable name! 您是否注意到argv[0]始终是您的可执行文件名称! this means whenever you need to print your executable name use argv[0] instead of hard code name of your executable while writing code, so that if you recompile and give new name to your executable then argv[0] always prints correct name. 这意味着每当您需要打印可执行文件名时,在编写代码时使用argv[0]而不是可执行文件的硬代码名称,这样如果您重新编译并为您的可执行文件赋予新名称,则argv[0]始终打印正确的名称。 You should write code as follows: 您应该编写如下代码:

int main(int argc, char* argv[]){
  :
  :// some other code
  if(argc < min_number_of_arguments){
      fprintf(stderr, "Error: wrong number of arguments passed!\n");
      fprintf(stderr, "Usage: %s [first] [second] \n", argv[0]);
      exit(EXIT_FAILURE);
  }
  :
  :// some other code 
   return EXIT_SUCCESS;
}

You can't use strcmp() to compare to NULL . 您不能使用strcmp()来比较NULL Neither argument can be null. 两个参数都不能为空。 In this situation it doesn't make sense anyway. 在这种情况下,它无论如何都没有意义。 If the argument isn't present, argc will be < 3, and if it is somehow empty it will be zero length. 如果参数不存在,则argc将为<3,如果它以某种方式为空,则它将为零长度。 Never null. 永远不会。

Firstly, you shall always use strcmp(some_string, "") instead of strcmp(some_string, NULL) to check if a string is empty. 首先,您应始终使用strcmp(some_string, "")而不是strcmp(some_string, NULL)来检查字符串是否为空。

However in your problem you shall test 但是在你的问题中你应该测试

if (argc < 4)

That's because the executable itself is also in the array argv . 那是因为可执行文件本身也在数组argv Consider you're invoking something like ./a.out param0 param1 , then argc would be 3 and argv[0]="./a.out" , argv[1]="param0" , argv[2]="param1" . 考虑你正在调用类似./a.out param0 param1东西,然后argc将是3argv[0]="./a.out"argv[1]="param0"argv[2]="param1"

EDITED: 编辑:

Also, never test if(strcmp(argv[2], NULL) == 0) directly. 另外,永远不要直接测试if(strcmp(argv[2], NULL) == 0) Always test argc first. 始终先测试argc Since there is no grantee that what value would be stored in argv[argc+n] for n >= 0 由于没有受让人在argv[argc+n]存储的值为n >= 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM