49

My professor and a couple of students are arguing about whether argv is null terminated or not. My friend wrote a small program and it printed out null but another kid said that he is probably simply reading into blank memory. Can someone solve this discussion?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
jakehschwartz
  • 1,005
  • 2
  • 13
  • 32

2 Answers2

95

From the Standard:

5.1.2.2.1 Program startup
...
-- argv[argc] shall be a null pointer.

So, yes; argv is null terminated

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 1
    Wow, I didn't know that. Why then the argc anyway? – Christian Rau May 12 '11 at 00:33
  • 5
    I don't know **why**. But it makes writing some programs a little easier by avoiding having to walk the `argv` array just to count the arguments. – pmg May 12 '11 at 08:10
  • Umm.. why: argc: `if(argc <= 3) /* not enough arguments */` I think better than `if(sizeof(argv) / sizeof(argv[0]) <= 3)` – Jack Sep 03 '12 at 19:50
  • 9
    @Jack: `argv` is a pointer; `argv[0]` is also a pointer. In all likelihood `sizeof(argv) / sizeof(argv[0])` evaluates to `1` ... anyway, your idea is similar to what I said (not having to walk to `argv` array). – pmg Sep 03 '12 at 20:04
  • Still, the Operating System (in case of Linux, the ELF loader) has to walk argv, since it's only passed argv in execve(). – mic_e Sep 26 '12 at 10:02
  • I have noticed that getopt() can crash if argv[argc] is not a NULL pointer (when using it in the Clide library, https://github.com/gbmhunter/clide-cpp). – gbmhunter Mar 26 '14 at 02:55
  • @pmg But why is `char* argv[argc]` a pointer to `NULL` in general? Isn´t it actually an array of pointers to char? Like `char* a[i]` is also a pointer to char, not to `NULL` or `void`. – RobertS supports Monica Cellio Jan 04 '20 at 13:09
  • @RobertS: independent of the names used, by the c specification `char *argv[argc]` declares an array named `argv` capable of holding `argc` pointers to `char`. When passed to a function, the array gets converted to a pointer to its 1st element (so a pointer to pointer to `char` [this is why it is usual to see `main(int argc, char **argv)`]) losing information about size (`char *a[10]` has 10 elements; `char **a` is a pointer --- if the pointer points to an array, there is no way of knowing how many elements the underlying array has). – pmg Jan 04 '20 at 13:16
44

According to the standard, "argv[argc] shall be a null pointer" (5.1.2.2.1).

Steve M
  • 8,246
  • 2
  • 25
  • 26
  • Why and how did it become standard? Any idea? – Reigel Gallarde Sep 23 '10 at 02:15
  • 14
    @Reigel: The man page for `exec` from 1979 (http://plan9.bell-labs.com/7thEdMan/v7vol1.pdf) shows that this predates the standard by quite a bit, and contains a possible hint as to why it's this way: "Argv is directly usable in another execv because argv[argc] is 0." – bk1e Sep 23 '10 at 06:46