[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: One more C question




On Tue, May 02, 2000 at 05:31:21PM -0500, John Corey wrote:
> 
> Jeff Licquia wrote:
> > 
> > There's no way of finding the number of elements in an array "by
> > default".  For null-terminated character arrays (otherwise known as
> > strings), you can use strlen().  In the special case of argv, the
> > number of arguments is in argc, and (I believe) argv[argc] = NULL.
> > (That may be specific to some compiler I used, so don't quote me on
> > it.)
> > 
> > So, you could do this to get the length of the last argument:
> > 
> >   len = strlen(argv[argc-1]);
> 
> Aren't arrays kept contiguous in memory?  So do some math on the
> pointers, subtracting the last character in argv[argc-1] from argv[0]. 
> If not, then you'd have to do a for/while loop and add up the length of
> each string.

For regular arrays, yes.  So:

  int array[4][5];
  size_t size;

  size = sizeof(int)*4*5;

String arrays are a different beast.  Again, there's nothing wrong
with:

  char strings[80][5];

  size = sizeof(char)*80*5;

But argv is technically not a char[][]; it's a *char[].  That's an
array of pointers.  There's no guarantee that all of the pointers
point to areas of memory that are contiguous.

So, argv's actual layout is implementation-specific.  Some archs may,
indeed, make it a contiguous block; for example, in DOS the
traditional convention was for the command line to be passed in offset
0x80 off the segment, and some compilers simply populated argv with
code something like 's/ /\0/' on that space (not in regex code of
course).  But there's no reason why a system couldn't, say, allocate a
bunch of 1024-byte buffers, copy all the args into them, and populate
argv with pointers to them.  Under this system, your pointer
arithmetic would always return 1024*argc.

BTW, this is also likely not correct:

  char *strings[5];
  size_t index, size;

  for (index = 0; index < 5; index++)
    strings[5] = (char *) malloc(1024);

  size = ((int)strings[4]) - ((int)strings[0]);

Again, with malloc there's no guarantee that the space will be
contiguous.  (Although, in this particular case, you'd be more likely
to just 1024*5 = 5128, and be done with it.)

I guess this is a long way to say: Yep.  You're stuck with:

  size = 0;
  for (index = 0; index < argc; index++)
    size += strlen(argv[index]);

--
To unsubscribe, send email to majordomo@luci.org with
"unsubscribe luci-discuss" in the body.