C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old June 20th, 2003, 01:24 PM
notsoevil notsoevil is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Posts: 26 notsoevil User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation 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.

Reply With Quote
  #2  
Old June 20th, 2003, 02:01 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 3,868 dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 1 Month 2 Days 3 h 14 m 44 sec
Reputation Power: 480
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 02:43 PM.

Reply With Quote
  #3  
Old June 20th, 2003, 02:10 PM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
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);

Reply With Quote
  #4  
Old June 20th, 2003, 02:33 PM
notsoevil notsoevil is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Posts: 26 notsoevil User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation 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.

Reply With Quote
  #5  
Old June 20th, 2003, 05:56 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
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)

Reply With Quote
  #6  
Old June 20th, 2003, 06:38 PM
Analyser's Avatar
Analyser Analyser is offline
*bounce*
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Delft, The Netherlands
Posts: 510 Analyser User rank is Corporal (100 - 500 Reputation Level)Analyser User rank is Corporal (100 - 500 Reputation Level)Analyser User rank is Corporal (100 - 500 Reputation Level)Analyser User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 2 Days 20 h 44 m 4 sec
Reputation Power: 9
Send a message via ICQ to Analyser
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/

Reply With Quote
  #7  
Old June 20th, 2003, 06:58 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
yeah i suppose it's that simple (and obvious). ok, thanks.

Last edited by balance : June 20th, 2003 at 07:01 PM.

Reply With Quote
  #8  
Old June 20th, 2003, 08:38 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
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);
}

Reply With Quote
  #9  
Old June 21st, 2003, 06:06 AM
BigBadBob BigBadBob is offline
status unknown
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Posts: 262 BigBadBob User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
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.

Reply With Quote
  #10  
Old June 21st, 2003, 08:22 AM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
Quote:
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:
Quote:
Pardon my ignorance on this, but I am new to C...

Reply With Quote
  #11  
Old June 21st, 2003, 09:13 AM
pschmerg pschmerg is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2002
Location: Blacksburg VA/Philly PA
Posts: 38 pschmerg User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 29 m
Reputation Power: 6
Send a message via AIM to 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.

Reply With Quote
  #12  
Old June 21st, 2003, 11:34 AM
BigBadBob BigBadBob is offline
status unknown
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Posts: 262 BigBadBob User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
Quote:
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.

Reply With Quote
  #13  
Old June 21st, 2003, 11:35 AM
BigBadBob BigBadBob is offline
status unknown
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Posts: 262 BigBadBob User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
Quote:
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.

Reply With Quote
  #14  
Old June 21st, 2003, 04:28 PM
3dfxMM 3dfxMM is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2002
Posts: 266 3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level)3dfxMM User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 3 Days 21 h 16 m 35 sec
Reputation Power: 13
Quote:
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.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > determining number of elements from an array pointer


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump