Fusionmate
Fusionmate

Reputation: 689

Get the total of item in "char *namelist[]" in C

I have an array of names stored in char *namelist[]. When I pass it to a function, I'm unable to display all of the names in the namelist:

int ReadListOfName(const char* names[])
{
  //Note: I always get the len = 1
  //      Anyway I can get total items in names

  int len = sizeof(names)/sizeof(char*);
  for (i=0; i<len; i++)
    printf("%d-%s\n",i,names[i]);

  return 0;

}

int main(void)
{
  const char* names[] = {"a","b","c"};
  ReadListOfName(names);
  return 0;
}

What's the problem?

Upvotes: 0

Views: 178

Answers (6)

Jeyaram
Jeyaram

Reputation: 9484

sizeof(AnyPointer) gives word size. In case of 32-bit OS, 4 will be returned. similarly 8 will be returned in 64-bit machine.

So sizeof(char*) == sizeof(float*) == sizeof(int*) is true.

If your OS is 32-bit,
sizeof(names) will be 4.
sizeof(char*) also 4.

Obviously you will get len = 1.

Upvotes: 0

Aftnix
Aftnix

Reputation: 4599

you should pass an additional argument which will explicitly mention the length of the array. and where you are initializing setup some MACRO to fiddle with sizeofs.

Upvotes: 0

alk
alk

Reputation: 70971

As the other answers already explain what happens to the array reference when passing it to the function, please find an approach to solve the issue without adding another parameter to the method printing the names.

You might like to add a stopper element to your list like so:

#include <stdio.h>

int ReadListOfName(const char ** names)
{
  for (int i=0; names[i]; i++)
    printf("%d-%s\n",i,names[i]);

  return 0;
}

int main(void)
{
  const char* names[] = {"a","b","c", NULL}; /* Please note the additional, last element. */
  ReadListOfName(names);
  return 0;
}

The essential difference of this approach to the one passing two arguments discribing the list names[], is the fact that its use is less error-prone as the information of the list's size is drawn from the list itself, but from a second independently provided value.

Upvotes: 1

AusCBloke
AusCBloke

Reputation: 18502

You'll need to pass in another argument to ReadListOfName specifying the length of the array or have a terminating value in your array like argv does. When passed to a function, an array will decay to a pointer; a char*[] will decay to a char**, as you're passing the address of the first element in the array. Therefore your function is in fact interpreted as:

int ReadListOfName(const char **names)

And you're actually equating sizeof(char**)/sizeof(char*), which won't give you the number of elements in the array (it'll probably give you 1).

Add a length argument and then just calculate len before passing it ReadListOfName.

Note that rather than dividing sizeof(names) by sizeof(char*) to get the number of elements in the array, you can instead divide by sizeof(*names), and you wouldn't need to worry about changing char* if you change the type of the elements in names:

int len = sizeof(names)/sizeof(*names);

Upvotes: 1

Rohan
Rohan

Reputation: 53366

int ReadListOfName(const char* names[])

In this names essentially becomes char ** rather than char * [] as defined your main.

Upvotes: 1

cnicutar
cnicutar

Reputation: 182664

int len = sizeof(names)/sizeof(char*);

This doesn't get you the number of elements, sizeof doesn't do what you want on pointers. You have to pass the length as an additional argument to the function. Also discussed in this C FAQ. You could try:

int ReadListOfName(const char* names[], size_t len)
/* ... */

ReadListOfName(names, sizeof(names)/sizeof(names[0]));

Upvotes: 4

Related Questions