3

I need to pas two command line arguments and I tried the following:

#include <stdio.h>
#include <stdlib.h>

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(atoi(argv[1]),atoi(argv[2]));
    }

    printf("\n");
    return 0;
}

Output:

michi@michi-laptop:~$ ./power
Usage ./power arg2 arg2
(EG: ./power 2 3)
michi@michi-laptop:~$ ./power 2 3
Res = 8

Everything until here is ok, but if when save argv[1] and argv[2] in variable like this:

int base = atoi(argv[1]);
int exp = atoi(argv[2]);

I get Segmentation fault

code:

#include <stdio.h>
#include <stdlib.h>

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

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

    int base = atoi(argv[1]);
    int exp = atoi(argv[2]);

    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(base, exp);
    }

    printf("\n");
    return 0;
}

But when I use Atoi inside printf everything is OK:

#include <stdio.h>
#include <stdlib.h>

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

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

    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(atoi(argv[1]), atoi(argv[2]));
    }

    printf("\n");
    return 0;
}

My question is:

is this issue happen because of Atoi?

is this issue happen because I try to access argv[1] and argv[2] and they are not exists when I type ./program?

If I type ./program 2 3 everything is ok, which makes me think that segmentation fault happens because I try to access a memory location which doesn't belong to me at that point.

Michi
  • 5,175
  • 7
  • 33
  • 58

3 Answers3

4

is this issue happen because I try to access argv[1] and argv[2] and they are not exists when I type ./program?

Yes, the problem is that you are trying to access the command lines arg's before verifying whether they are present or not.

In the second example code snippet, assign the values to the variables base and exp only after making sure that the input is available.

int base;
int exp;

if (argc != 3) {
    printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
    exit(1);
}else{
    /* Assign the values here, as it is verified that arg's are obtained from cmd line*/
    base = atoi(argv[1]);
    exp = atoi(argv[2]);
    power(base, exp);
}

In the above program it is made sure that I reference the args (argv[1] and argv[2]) only if they are passed as commandline arguments when the program is executed.

Santosh A
  • 5,173
  • 27
  • 37
2

is this issue happen because I try to access argv[1] and argv[2] and they are not exists when I type ./program?

It is because you're not checking for null. argv[1] and argv[2] could be null if no argument is passed in. This causes segmentation fault.

int base = atoi(argv[1]);
int exp = atoi(argv[2]);

Instead, try this

int base = 0;
int exp  = 0;

if(argv[1] && argv[2])
{
  int base = atoi(argv[1]);
  int exp = atoi(argv[2]);
}

Or you could check the argument count to make sure you have 2 arguments passed in.

if(argc > 2)
{
  int base = atoi(argv[1]);
  int exp = atoi(argv[2]);
}
Vivek Vijayan
  • 337
  • 5
  • 19
1

When you call atoi on argv[ > 0] when there's no argument, you're accessing out of bounds memory, which is Undefined Behavior.

By the C Standard definition, accessing out of bounds memory is Undefined Behavior.


Might Interest you

Community
  • 1
  • 1
Enzo Ferber
  • 3,029
  • 1
  • 14
  • 24
  • Why should the OP have power() return an int? He doesn't try to use the computed value anywhere except for printing it inside the method. Also, there is another serious problem - what happens if the second entry is a negative number? – FredK Sep 18 '15 at 15:12
  • @FredK I didn't see that! I'm so used to `power` functions returning the result that I assumed that this one also worked like this! My bad. Thanks for pointing it out. – Enzo Ferber Sep 18 '15 at 16:12