0

I want to pass an array as a parameter. I want the other function to calculate the array size. So array size is not passed as a parameter. How do I do this?

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

void myFunction1(int tmpints[])
{
    int arraysize = *(&tmpints + 1) - tmpints;
    printf("In myFunction1....\n");
    printf("   size is :%d\n",arraysize);
    printf("   start is :%p\n",*(&tmpints + 1));
}

void myFunction2(int tmpints[],int* EndP)
{
    printf("In myFunction2....\n");
    printf("   size is :%d // correct\n",EndP-tmpints);
    printf("   start is :%p\n",*(&tmpints + 1));
}

int main()
{
    int tmpintarray[] = {4,3,2,9,8,7};
    printf("In main....\n");
    printf("   start is :%p\n",*(&tmpintarray + 1));
    printf("   size is :%d // correct\n",*(&tmpintarray + 1)-tmpintarray);
    myFunction1(tmpintarray);
    myFunction2(tmpintarray,*(&tmpintarray + 1));
}

results

In main:

start is :0x7ffc7e593a38
size is :6 // correct

In myFunction1:

size is :-529944200
start is :(nil)

In myFunction2:

size is :6 // correct
start is :0x7ffc7e593a40
Oleg Shparber
  • 2,732
  • 1
  • 18
  • 19
Dean Smith
  • 27
  • 4
  • You can't do that. The argument is a pointer, not an array – `int tmpints[]` is equivalent to `int* tmpints` – molbdnilo May 03 '20 at 09:23
  • 1
    `*(&tmpintarray + 1)` has undefined behaviour, so it's just bad luck that you get the expected answer. – molbdnilo May 03 '20 at 09:26
  • @molbdnilo it's not luck , read last part of my answer to find out why it's working – emaditaj May 03 '20 at 10:40
  • i respect that you are trying everything so you learn very deep ,as a person who has done the same , i say it'll take you a lot of time to experiment everything , don't do if you are not a teenager with lots of free time ...(this is not advise , i answered the real problem in question in answers ,see the edit) – emaditaj May 03 '20 at 10:45

3 Answers3

1

Using std::vector makes things clearer and simpler.

Tiger Yu
  • 744
  • 3
  • 5
0

sizeof doesn't help when dealing with an array value that has decayed to a pointer: even though it points to the start of an array, to the compiler it is the same as a pointer to a single element of that array. A pointer does not "remember" anything else about the array that was used to initialize it.

So you have to pass the array size as a parameter.
(int)sizeof(tmpintarray)/sizeof(tmpintarray[0])

Dean Smith
  • 27
  • 4
  • Why cast to `int`? The original unsigned value makes more sense. Plus that expression parses as `((int) sizeof(tmpintarray)) / sizeof(tmpintarray[0])`, so you're only casting the numerator, and then the division result will probably have unsigned type again anyway. – aschepler May 03 '20 at 11:06
0

in c++ arrays only exist on stack (dynamically allocated arrays are just a box of memory with x*SingleObjectSize size not array ).

when you pass a pointer of start of array to another function (and this is the only way you can pass it) it's no longer on the stack of the target fucntion so sizeof won't work by looking at stack (actully sizeof is precompile thing that hardcodes the size as size_t in the code you write it)

you may ask if it hardcodes and is precompile then why the compiler doesn't hardcode the same value in when passed to another function , answer is clear :: a function can be called many other functions and from many places and each time it can have an array of various size

the solution is to pass the size along with the array or use a modern type like std::vector witch saves size in size_t and carries it when passed (witch has even more memory usage )

why your code doesn't work in the function :: in the main function when you enter (&tmpintarray + 1) you are getting address of arrray and adding by 1 , adds the sizeof(tmpintarray) witch is 24 because it's refering to array and it has the array size in stack

if we consider address of tmpintarray as A *(&tmpintarray + 1) returns {(char)A+24} or {(int)A+6} then you you subtract by A you get 6, because A+6 is 6intergets forward than A , and print f successfully prints it

but when you do it in myFunction1 , tmpints is no longer an array and doesn't have the size of 24 (0x18) , it's a pointer to an int and has the size of 4 so when you add by +1, you only add 4bytes to address of tmpints so - won't give you 24 anymore

but in myFunction2 you are passing address added by 24 (witch is calculated in main function and main has sizeof(tmpintarray) as 24 not 4) so it works

emaditaj
  • 177
  • 9
  • Stack storage isn't really related to this, and a C++ array certainly doesn't have to be "on the stack". And passing by pointer to start of array is not the only way to pass a raw array: `void f(int (&tmpints)[6]);` or `template f(int (&tmpints)[N]);` would work, if we want a function that does know its array's size at compile time. – aschepler May 03 '20 at 11:03
  • @aschepler when writing void f(int (&tmpints)[6]); you are explicitly determining the array size that can be passed ,so you limit the function for arrays of that size ,it's the same as hardcoding array size yourself, the template is the same too , it auto rewrites functions for each array size you pass (will result is much larger code) – emaditaj May 03 '20 at 11:26
  • @aschepler as said you can have dynamiclly allocated arrays, by their different thing in root, they store the memory size be a varaible before that start address of array and when sizeof used ,it returns that value in runtime... but when sizeof used for a stack array ,it just changes to a hardcoded value ... dynamilly allocated memory is a one chuck of memory that is spilt and constructed with the value type and storing the whole size in other place , but stack array are real arryas, their a line of objects fllowed eachother , without strong the whole count in any memory – emaditaj May 03 '20 at 11:31
  • Yes, except it's not a terrible code smell like "hardcoding array size". Just a note on "this is the only way you can pass it". – aschepler May 03 '20 at 11:31
  • No, `sizeof` will definitely not get you the real size of a dynamically allocated array (even if the implementation does store the size before the start, which is not guaranteed). – aschepler May 03 '20 at 11:32
  • @aschepler (sizeof) true, sorry for my mistake about returning sizeof dynamically allocated array , i thought of the way free() and delete[] determines the size – emaditaj May 03 '20 at 11:37