#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    26
    Rep Power
    0

    determining number of elements from an array pointer


    I am passing an array to function for munging and need to loop through it while there. Since passing the array to the function is effectively passing a pointer to the array to the function, I'd like to know how to determine the number of elements in the array without sending it as another parameter to the function.

    sizeof does not work for a pointer, as shown below:

    Code:
      int array[5] = {1,2,3,4,9};
      int size = sizeof(array)/sizeof(array[0]);
      
      printf("size is %d\n", size);
      // size is 5
    
      
      int *array_ptr;
      array_ptr = &array[0];  // pretty much what my function would get
      size = sizeof(array_ptr)/sizeof(array_ptr[0]);
      
      printf("size is %d\n", size);
      // size is 1
    Is this possible, or do I need to pass along the size to the function as well. Seems very untidy to me to produce a variable in main to hold the size, when the function itself is the only thing that needs to use said variable.

    Pardon my ignorance on this, but I am new to C and I am a long time Perl programmer, so my view on things is a bit skewed.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,251
    Rep Power
    2222
    Basically, that is about the size of it -- i.e., needing to pass along the size to the function as well. A C pointer does not carry with it information about the size of the array, only about the size of each item in the array (due to knowing the data type).

    Your solution of passing in the array size as a parameter is one possibility. Here are a couple more:

    1. A bit of a kludge, perhaps.
    Create a struct that contains the array and the number of items in the array, so you just pass to the functions a pointer to this struct; eg:
    Code:
    struct Array
    {
        int  size;
        int  array[5];
    };
    In C++, you can convert this into a class.

    2. Fairly commonly done.
    Add an extra item to the array that serves as an array terminator. The value that item contains must be one which would not occur in a data item, for example:
    1. Terminate a char array with a NULL ('\0'). (done automatically when you initialize a char array with a string)
    2. Terminate an array of character strings with an empty string.
    3. Terminate an array of numbers with an invalide value, such as -1 for positive integers or INT_MAX or INT_MIN for signed integers.

    E.g.:
    Code:
    char *strings[] = {"First string","Second string",""};
    
    int  lengths[] = {34,65,22,656,4,1,0,23,543,-1};
    
    int  int_array[] = {1,2,3,4,-3,-5,INT_MAX};
    With Option #2, you can scan the array for the special terminating value to get the number of items in the array.

    Hope this helps.
    Last edited by dwise1_aol; June 20th, 2003 at 03:43 PM.
  4. #3
  5. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    it doesnt work b/c size of a pointer is always 4 bytes, which is the size of an address. you can use strlen instead with a pointer to the string, like this:
    Code:
     char *ptr = "ABCDE";
    
            int size_array_ptr = 0;
    
            size_array_ptr = strlen(ptr);
    
            printf("size_array_ptr = %d\n", size_array_ptr);
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    26
    Rep Power
    0
    I've just passed the number of elements along with the function, though Option 1 seems interesting for future, more complicated data that needs to be passed.

    I'm not doing this on a string, so strlen won't work.

    Thanks for all the help.
  8. #5
  9. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    i thought this was going to be a great time to use sizeofs in a define, but it doesn't work. i'm confused on that.

    i thought defines ignored usual c laws and worked more like a text editor. i also thought that the sizeofs got calculated and replaced at compile time, so bearing those two thoughts in mind i could have sworn this was going to work, but it doesn't:
    Code:
    /* doesn't work */
    #include <stdio.h>
    #define SIZE sizeof(array)/sizeof(array[0]) 
    
    main()
    {
    	void function(int *p);
    	int array[] = {1,2,3,4,9};
    	function(array);
    }
    
    void function(int *p)
    {
    	int i;
    	for(i = 0; i < SIZE; i++, p++)
    		printf("%d\n", *p);
    }
    the error: `array' undeclared (first use in this function)
    which is refering to this line - for(i = 0; i < SIZE; i++, p++)

    it's now looking to me as if sizeof calculations do not occur at compile time then (which would explain it not working), but in my book it says sizeof is a compile-time operator. why doesn't that work then? (i know about the usual scope rules, but i was thinking defines aren't aware of scope rules)
  10. #6
  11. *bounce*
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2002
    Location
    Delft, The Netherlands
    Posts
    514
    Rep Power
    42
    Ok, just do what the preprocessor does. That gives you:

    Code:
    void function(int *p)
    {
    	int i;
    	for(i = 0; i < sizeof(array)/sizeof(array[0]); i++, p++)
    		printf("%d\n", *p);
    }
    Obviously, array is well out of scope; you're trying to refer to a variable that's declared in a different function (namely main()). So it's actually a scope problem, rather than a "sizeof" problem.
    "A poor programmer is he who blames his tools."
    http://analyser.oli.tudelft.nl/
  12. #7
  13. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    yeah i suppose it's that simple (and obvious). ok, thanks.
    Last edited by balance; June 20th, 2003 at 08:01 PM.
  14. #8
  15. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    well notsoevil, what about just a usual bog standard define for this then? no need to pass the size of the array to the function.
    Code:
    #include <stdio.h>
    #define SIZE 5
    
    main()
    {
            void function(int *p);
            int array[SIZE] = {1,2,3,4,9};
            function(array);
    }
    
    void function(int *p)
    {
            int i;
            for(i = 0; i < SIZE; i++, p++)
                    printf("%d\n", *p);
    }
  16. #9
  17. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Balance, I agree that works fine for small examples but it can become a little cumbersome in large programs.

    At the end of the day, at some point within your program the size of your array will be known. After that, it's the simplest thing in the world to simply pass the value to functions that need it.
  18. #10
  19. No Profile Picture
    .
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2002
    Posts
    296
    Rep Power
    12
    Balance, I agree that works fine for small examples but it can become a little cumbersome in large programs
    well, there's a possability that this may be a small example and the original poster is not aware of defines used to achieve what they're wanting to do:
    Pardon my ignorance on this, but I am new to C...
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2002
    Location
    Blacksburg VA/Philly PA
    Posts
    38
    Rep Power
    13
    If you really have your heart set on passing in just a pointer to an array you could always use pointer arithmetic, and then before using the index put it in a try catch block to see if the address is valid. This does work but I wouldn't reply upon it for you are not sure what's lurking outside of the memory you own.
  22. #12
  23. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Originally posted by balance
    well, there's a possability that this may be a small example and the original poster is not aware of defines used to achieve what they're wanting to do:
    Yes, I understand. I wasn't criticising your suggesting, merely pointing out a limitation.
  24. #13
  25. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Originally posted by pschmerg
    If you really have your heart set on passing in just a pointer to an array you could always use pointer arithmetic, and then before using the index put it in a try catch block to see if the address is valid. This does work but I wouldn't reply upon it for you are not sure what's lurking outside of the memory you own.
    Can you provide a short example to demonstrate what you mean? It sounds a little dodgy to me.
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2002
    Posts
    272
    Rep Power
    19
    If you really have your heart set on passing in just a pointer to an array you could always use pointer arithmetic, and then before using the index put it in a try catch block to see if the address is valid. This does work but I wouldn't reply upon it for you are not sure what's lurking outside of the memory you own.
    The problem with this approach is that the memory can be outside of the array but still in the program's address space.

IMN logo majestic logo threadwatch logo seochat tools logo