0

The following program runs fine if 3 characters are given however as soon as 4 or more characters are given - the argv[1] becomes null. why?

#include <stdio.h>

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

    char name[5];

    printf("Enter yor name:");
    fgets(name, 10, stdin);     // delibrate 

    printf("name is: %s \n", name);
    printf("argv is %s \n", argv[1]);
    printf("Final Output - %s %s\n", argv[1] , name);
}

Invoking by - ./test hello

How and why does the difference in lengths of fgets and array produce this behavior?

lynxx
  • 544
  • 3
  • 18
  • `// delibrate`. If you deliberately break the C standard then the result is undefined behaviour. Which means any behaviour can occur and it is not productive to try and explain it. – kaylum Mar 03 '20 at 05:14
  • Actually, I take that back (for now). What did you actually enter for the name? If was longer than 3 characters then my original comment holds as that causes a buffer overflow and hence undefined behaviour (I think that's what you meant but it isn't entirely clear whether "3 characters" refers to argv[1] or the stdin input). – kaylum Mar 03 '20 at 05:17
  • 1
    UB. You overflow `name` (4 characters + newline + NUL terminator requires 6 bytes). – jamesdlin Mar 03 '20 at 05:37
  • @kaylum I understand It is something to do with buffer or garbage values. However, I fail to understand how can it be as I am passing `Hello` as `argv[1]` – lynxx Mar 03 '20 at 05:57
  • 2
    UB means that anything can happen. The data is probably trampling the pointer value in `argv[1]` and not the data that it points at. But the whole question is really pointless. You deliberately risk undefined behaviour, and you must accept anything that happens after you invoke the undefined behaviour. – Jonathan Leffler Mar 03 '20 at 06:03
  • Terminating zero is likely overwriting the least significant byte of `argv` pointer (which is saved on stack in the beginning of a function), so now it points at some random location on the heap (which happens to contain NULL) when you're dereferencing it. – Alex Skalozub Mar 03 '20 at 06:15

1 Answers1

-1

In int main(int args, char* argv[]) argv are command line parameters (actually argments passed to the program), not the input you take.

If your executable is a.out,

then for

a.out

argc will be 1 and argv[1] will be undefined.

For a.out test, argc will be 1 and argv[1] will be "test".

Reference: https://en.cppreference.com/w/c/language/main_function

Edit I think you are facing the problem because your buffer size is smaller. You are reading more than you have allocated. This has undefined behaviour in C.

For following code:

#include <stdio.h>

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

    char name[11];

    printf("Enter yor name:");
    fgets(name, 10, stdin);     // delibrate 

    printf("name is: %s \n", name);
    printf("argv is %s \n", argv[1]);
    printf("Final Output - %s %s\n", argv[1] , name);
}

I am getting

>./test test
Enter yor name:test
name is: test

argv is test 
Final Output - test test
doptimusprime
  • 9,115
  • 6
  • 52
  • 90
  • 2
    What you have said is all true but doesn't seem to answer the actual question. OP runs the program like this `./test hello` and claims that `argv[1]` is NULL. – kaylum Mar 03 '20 at 05:29
  • @kaylum Yes, I run the program like that and then It will prompt for the name. If I enter `1234` for the name, `argv[1]` becomes null. However, it works fine for `123` or shorter name. – lynxx Mar 03 '20 at 05:53
  • Also note that one space is to be reserved for null character. – doptimusprime Mar 03 '20 at 06:08