Reputation: 689
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
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
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
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
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
Reputation: 53366
int ReadListOfName(const char* names[])
In this names
essentially becomes char **
rather than char * []
as defined your main
.
Upvotes: 1
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