Prisoner.627
Prisoner.627

Reputation: 35

Why is Segmentation fault happening?

int     main(int    argc, char* argv[])
{
    int num = atoi(argv[1]);

    if (argc < 2 || argc > 3) {
        fprintf(stderr, "Usage:\tpartner1 (nameIndex)\n");
        exit(EXIT_FAILURE);
    }
    if (num < 0 || num > 2) {
        printf("nameIndex must be in[0, 1, 2]");
        exit(EXIT_FAILURE);
    }

output

./parent1

Segmentation fault

Im getting Segmentation fault and I am not sure why this is happening. I know the second if statement is working fine because if I do input ./partner1 4 or ./partner1 -1, the output is

nameIndex must be in[0, 1, 2]

Why is this happening?

Thanks

Upvotes: 0

Views: 76

Answers (2)

Thomas Jager
Thomas Jager

Reputation: 5265

The argv argument of main is a pointer to an array of argc pointers to strings, followed by a NULL pointer. argv[0] points to a C-string of the program's name, and argv[1] to argv[argc - 1] will point to the command-line arguments.

For example, if you execute a program like ./program hello world, argc would be 3, and argv be a pointer to an array that looks like:

+------------------------+----------------------+----------------------+------+
| <pointer to "program"> | <pointer to "hello"> | <pointer to "world"> | NULL |
+------------------------+----------------------+----------------------+------+

If you've confirmed that argc == 3, then you know that you can access the strings pointed-to by argv[0], argv[1], and argv[2].

With no arguments, executing ./program, you'll have something like:

+------------------------+------+
| <pointer to "program"> | NULL |
+------------------------+------+

You can see that argv[1] is a NULL pointer, which can't be dereferenced (you can't access the data to which it points).

The function atoi will access the string to which the argument points, and that can't be NULL.

You should always check the value of argc and/or step through the argv array one at a time, checking for NULL. Your code will access argv[1] before it checks the value of argc, causing the NULL pointer dereference which leads to the crash.

The line with atoi should be moved to after the point where you check argc.

Upvotes: 0

yhyrcanus
yhyrcanus

Reputation: 3813

Move int num = atoi(argv[1]); to below the argc check. That way, you'll only check argv[1] if you know it exists.

int     main(int    argc, char* argv[])
{
    if (argc < 2 || argc > 3) { 
        fprintf(stderr, "Usage:\tpartner1 (nameIndex)\n");
        exit(EXIT_FAILURE);
    }

    int num = atoi(argv[1]);

    if (num < 0 || num > 2) {
        printf("nameIndex must be in[0, 1, 2]");
        exit(EXIT_FAILURE);
    }

Upvotes: 1

Related Questions