-1

I just don't know how to explain my question precisely. So I wrote that title above.

Here is my confusion about a very simple program. Exactly, the results.

#include <iostream>
using namespace std;

char * tmp[]={"aaa", "bbb", "ccc"};//there are 3 members

int main(int argc, char* argv[], char* env[])
{
    cout << sizeof(env)/sizeof(char*) << endl;
    cout << sizeof(tmp)/sizeof(char*) << endl;
}

Results:1 3

What I want is the length of env[]. How can this possible that I got number 1 of env[], while the length of 'tmp'(3) is absolutely rigth.

There's no way that the length of env is 1, cause I tested it and the number is 47.

Why this happened? Thanks!

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
Echo_yang
  • 3
  • 3

4 Answers4

5

The difference is that tmp is an array, whereas env is a pointer. Arrays and pointers are different. It's a bit confusing because array syntax in a function formal parameter list is actually a pointer in disguise.

There is no way to get the number of elements pointed to by env using sizeof. You have to go through them until you find the NULL element terminating the list.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thx! I did go through them until find the null. Now I am aware that the defination of env is char**. I thought it should be char* env[]. – Echo_yang May 28 '14 at 15:35
1

The important thing to remember is that argv and env are pointers, not arrays. In the context of a function parameter declaration, T a[] and T a[N] are interpreted as T *a, so the types of both argv and env are char **, not char *[N].

The only way to determine how many elements each points to is by iterating through them until you find a NULL pointer:

size_t i;
for ( i = 0; argv[i] != NULL; i++ )
  ; // empty loop body

printf( "There are %zu elements in argv\n", i );

for ( i = 0; env[i] != NULL; i++ )
  ; // empty loop body

printf( "There are %zu elements in env\n", i );
John Bode
  • 119,563
  • 19
  • 122
  • 198
1

The language C has certain syntactical features that are convenient for the experienced programmer, but confusing for the new learner. While the syntax T * X[] looks the same in your two cases, they actually mean two very different things:

  • int a[] = { 1, 2, 3}; is the same as int a[3] = { 1, 2, 3 };. Here a is an array, and the size of the array is deduced from the initializer.

  • void f(int b[]) is the same as void f(int * b). Here b is a pointer, and the notation is merely suggestive of the fact that you should call f with a pointer to an element of an array. For instance, you could call f(a), or equivalently f(&a[0]), or even f(a + 2). But the declarator syntax is purely a cosmetic convenience, and b is not an array, but a pointer.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
0

This has little to do with these being parameters to main, sizeof anything is a compile time expression. Obviously, the environment and arguments passed to your program aren't. sizeof(array)/sizeof(element_type) is only the length of the array if that array was declared with a static size. Otherwise, sizeof(array) will be equivalent to sizeof(element*) (and because sizeof(char**) == sizeof(char*) you get 1 in your program).

Cubic
  • 14,902
  • 5
  • 47
  • 92