Segmentation fault with strcmp()

馋奶兔 提交于 2020-01-04 04:04:34

问题


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. But a segmentation fault error is being displayed.

I also tried with

if(argc < 3)

but it also didn't work...same segmentation fault...


回答1:


Why segmentation fault?

Because of code if(strcmp(argv[2], NULL) == 0), you are passing NULL as string pointer to strcmp() function; that try to deference at NULL to compare chars codes (e.g. acsii code) this cause undefined behavior at run time.

You should compare a string pointer with NULL using == as 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.

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.

    So when you pass no extra argument then argc == 1 e.g. ./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.

    So you can use of argc value to iterate in a loop to print arguments passed (other then executable)

     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. 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).

    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! 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. 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;
}



回答2:


Firstly, you shall always use strcmp(some_string, "") instead of strcmp(some_string, NULL) to check if a string is empty.

However in your problem you shall test

if (argc < 4)

That's because the executable itself is also in the array 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".

EDITED:

Also, never test if(strcmp(argv[2], NULL) == 0) directly. Always test argc first. Since there is no grantee that what value would be stored in argv[argc+n] for n >= 0




回答3:


You can't use strcmp() to compare to 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. Never null.



来源:https://stackoverflow.com/questions/19108368/segmentation-fault-with-strcmp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!