Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# Number of cells in array  in C/C++

Posted on 2013-11-04
Medium Priority
511 Views
Dear Experts,

I just tried one simple example of C/C++ program on 64-bit Linux in which just
want to find out of number of cells in one array.
But I get different result from main() and fn() function. Why ?
Could you help this ?

As I know, one double is 8-byte and my array cells are 5 so
sizeof(array) should be  40 . So the result,5, from main() is correct
but the result from fn() is 1 , Why ?

40/8-->5 in main() but 8/8-->1 in fn(), Why ?

Is it * str_numbers in fn() incorrect declaration ?

Duncan

``````#include <stdio.h>
#include<float.h>
int fn(double  * str_numbers)
{
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
//    printf("In f: %d\n", total);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

printf("No of cell in fn:%d\n",    fn(str_numbers));
return 0;
}
``````
0
Question by:duncanb7
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 11
• 8
• 4

LVL 46

Expert Comment

ID: 39621406
Hi duncan,

All that's passed to fn is the address of the array.  You can pass double*, double[], double[1000], etc from the calling function, but there's nothing in the address (or the passed object) that indicates the number of items in the array.  All that's passed is the address..

Good Luck,
Kent
0

LVL 13

Author Comment

ID: 39621416
int fn(double  str_numbers)
{

}

I tried it without * pointer but gave me the complier error, Why ?
0

LVL 46

Expert Comment

ID: 39621430
Parameters are passed by the C putting something on the stack.  (The stack is just a place in memory used to pass parameters and put the temporary variables used by the function.)  In your last example, function fn expects a double to be passed to it.  A single variable.  When the parameter is defined as a double*, the address of the variable will be passed.  When you think about passing a single variable, the difference is pretty subtle.  But when you think about passing an array it makes more sense.  You wouldn't want to put the entire array on the stack as the array could literally hold millions of items that would have to be copied to the stack and then back to the calling program.  Passing the address allows the function to access exactly the elements of the array that it needs.

When you pass a single item, you can pass by address or by value (by using the * or not), but the function must also be coded with the correct syntax to match how the variable is passed.

Kent
0

LVL 13

Author Comment

ID: 39621483
So how can I pass the array from str_number into the function that do the same
thing as in main ();
0

LVL 13

Author Comment

ID: 39621494
int fn(double  str_numbers[])
{

}

there is no complier error but the result of fn() is still 1 not 5, Why ?
0

LVL 31

Expert Comment

ID: 39621505
Hi duncanb7,

as Kdo mentioned above regardless whether you pass a 'double*' or a 'double[]' just a pointer to the first element of the array is passed to the function so within the function there's no chance to determine the size of the array.

So the only way to achieve what you want is to add an additional parameter to pass the size, i.e.:
int fn(double  * str_numbers, int total)
{
printf("size of whole:%d\n",sizeof(double)*total);
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

printf("No of cell in fn:%d\n",    fn(str_numbers,total));
return 0;
}

ZOPPO
0

LVL 46

Assisted Solution

Kent Olsen earned 1000 total points
ID: 39621510
As noted above, all that is passed is the starting address of the array.  There is no mechanism in C to pass an address and have the called function know anything more than the address, and by implication, the nature of the structure defined in the function header.  Length simply isn't passed.

You can "simulate" it with your own structure, but that's not the same thing.

typedef struct ArrayDescriptorDouble
{
int Size;

Then populate those two items and pass it (or it's address) to the function.  But passing a double* or double[], or double[100] passes only the starting address.  There is no guarantee or even implication of the length of the array.

Kent
0

LVL 13

Author Comment

ID: 39621540
dear zoppo,

the result is different between the code at main() and fn() even
the coding is same beside pass array into function.

The target I want to the number of array cells can be found in function fn()

Why such simple task can cost a lot of time ?
0

LVL 46

Expert Comment

ID: 39621572
Hi Duncan,

The short answer is because the called function doesn't know the size of the array.  The C convention is that because the called function doesn't know, 1 is assumed.  Both Zoppo and I have been trying to explain why that is instead of giving a 1 sentence answer that amounts to "because that's the way it is".

Kent
0

LVL 31

Expert Comment

ID: 39621584
Ok, maybe you should first think about the sizeof operator. You can read something about it (including samples similar to your problem here) i.e. at http://en.wikipedia.org/wiki/Sizeof

There you'll fine in most cases, sizeof is a compile-time operator, and that's exacly what's the cause for the difference between instantiating an array like
double a[] = { 1.0, 2.0, 3.0 };
int s = sizeof( a ); // will be 3*sizeof(double)
and passing an array like
void fn( double a[] )
{
int s = sizeof( a ); // will be sizeof( double* )

This is because only in the first case the compiler can determine the size of the array at compile time, for the second case there's no way to determine the size of the array, neither ar compile time nor at runtime.

ZOPPO
0

LVL 13

Author Comment

ID: 39621601
<link deleted because it violates site guidelines for off site content COBOLdinosaur, Topic Advisor>

Arrays decay to pointers in function calls. It's not possible to compute the size of an array which is only represented as a pointer in any way, including using sizeof.

So it is impossible to pass array into function for sizeof , I found a lot in google there
are a lot people experienced the same issue  but not solved and just do sizeof and pass
result of sizeof into function

In other words, can't sizeof array in function ,
0

LVL 46

Expert Comment

ID: 39621616
>> In other words, can't sizeof array in function

You CAN use sizeof() within a function.  It returns the size of the object passed.  What is passed is the address of the array and sizeof() dutifully returns 1, the number of addresses passed.
0

LVL 13

Author Comment

ID: 39621630
yes it can sizeof() in function but with the result we not expect so
we refer can't sizeof () in function if array is passed into it

Anyway, any other methods, we can
get the number of cells in array in function  () when array is passed into function(0 ?
0

LVL 13

Author Comment

ID: 39621638
Any now I know why like PHP and node.js at server-side more than C/C++
0

LVL 46

Expert Comment

ID: 39621641
No.  If it's critical that the function knows the number of items in the array, you'll need to pass that as a separate parameter or use something like the structure container that I showed above.

Kent
0

LVL 13

Author Comment

ID: 39621648
I tried yours but the result is same as before, Could you send me you complete code
for us ?

``````#include <stdio.h>
#include<float.h>
typedef struct ArrayDescriptorDouble
{
int Size;
int fn(double   str_numbers[])
{
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
//    printf("In f: %d\n", total);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

printf("No of cell in fn:%d\n",    fn(str_numbers));
return 0;
}
``````
0

LVL 31

Accepted Solution

Zoppo earned 1000 total points
ID: 39621664
Well, if you get more familiar with C/C++ you'll see sizeof in a function leads to expected results too ;o)

BTW, to avoid confusion I would suggest to avoid [] in function declarations, it is absoluteley the same as passing a pointer like in void fn ( double* a );.

And: You can't really compare C/C++ with PHP or Javascript. These are scripting languages with dynamic type system which internally use a lot of functionality to hide such details form the user, in C/C++ the user has to implement such things on a quite low-level base.

To do it like Kdo suggested you need to even use the declared structure, i.e.:
typedef struct ArrayDescriptorDouble
{
int Size;

{
int total = pData->Size;
printf("size of whole:%d\n",total);
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

data.Size = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("No of cell in fn:%d\n",    fn( &data ));
return 0;
}

ZOPPO
0

LVL 46

Expert Comment

ID: 39621668
Adding a structure definition doesn't really help unless you use it in the program.  :)

In this case, you probably just want to modify the function *fn* and pass the length.

``````#include <stdio.h>
#include<float.h>

int fn(double   str_numbers[], int size)
{
int total = size * sizeof(str_numbers[0]);

printf("In f: %d\n", total);
printf("size of whole:%d\n", size);
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
//    int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

printf("No of cell in fn:%d\n", fn (str_numbers, sizeof (str_numbers)));
return 0;
}
``````
0

LVL 13

Author Comment

ID: 39621692
dear zoppo,

your code is working and result are all 5  and only one array arg pass into fn()
that is what I want. I don't want to pass two argv into function() as Kda did but
his idea suggestion also help to finish this thread.

Last question, since I am not really fimilar with C,
when I complier the following code, that will give me
warning such as
10:warning:incompatible implict declaration of bulit-in function "printf" in
18:warning:incompatible implict declaration of bulit-in function "printf" in

COuld I avoid this warning ?

``````typedef struct ArrayDescriptorDouble
{
int Size;

{
int total = pData->Size;
printf("size of whole:%d\n",total);
}

int main ()
{
double  str_numbers[5] = {23000.678,23010.22,23800.345,22320.12,20345.456};
int total = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("size of whole:%d\n",sizeof(str_numbers));
printf("size of one cell:%d\n",sizeof(str_numbers[0]));
printf ("No of  cell In main: %d\n", total);

printf("%s\n","===========================================");

data.Size = sizeof(str_numbers)/sizeof(str_numbers[0]);
printf("No of cell in fn:%d\n",    fn( &data ));
return 0;
}
``````
0

LVL 13

Author Closing Comment

ID: 39621701
Thanks for your suggestion and final solution

If possible, please also answer the warning issue after complier zoppo's code

Duncan
0

LVL 46

Expert Comment

ID: 39621714
Make sure that the program includes:

#include <stdio.h>

at the top of the source code.

Kent
0

LVL 31

Expert Comment

ID: 39621725
Hm - I guess a type-or signed/unsigned mismatch warning could occur at
> data.Size = sizeof(str_numbers)/sizeof(str_numbers[0]);
since ADD_t::Size is of type int (which most probably is a 32-bit signed type) while sizeof returns a size_t (in your case I guess it's an unsinged, 64-bit type).

So you should change ADD_t to look like this:

typedef struct ArrayDescriptorDouble
{
size_t Size;

If this doesn't help please post the exact warning ...

ZOPPO
0

LVL 13

Author Comment

ID: 39621760
Thanks Kdo,

after add back stdio.h the warning is gone.

This thread is trying practise more C  code before making decision on
replacing  some huge some mathematical PHP code by C/C++ or
node.js on my server.

C and node.js in speed is much faster than PHP ,and PHP and Javascript code(node.js) is
much easier to use than C/C++.

Anyway, this might be next topic

Hava a nice day
Duncan
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SSH (Secure Shell) - Tips and Tricks As you all know SSH(Secure Shell) is a network protocol, which we use to access/transfer files securely between two networked devices. SSH was actually designed as a replacement for insecure protocols that senâ€¦
I. Introduction There's an interesting discussion going on now in an Experts Exchange Group â€” Attachments with no extension (http://www.experts-exchange.com/discussions/210281/Attachments-with-no-extension.html). This reminded me of questions thaâ€¦
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
###### Suggested Courses
Course of the Month9 days, 9 hours left to enroll