Hello, I am running into trouble with (what I thought would be) a simple algorithm that takes in an int array, and returns the number of elements in the array. It seems to work with arrays with only one digit, but does not work with arrays with int values >9 or <-9 . I was under the impression that pointer arithmetic takes into account the size of the elements in the array, but no matter what changes I make, arrays with multiple digit values always seems to run off the array with this function. Does anyone have any ideas on what I might be doing wrong?
int Alg::getSize(int array[])
{
int size = 0;
int* ptr = &array[0];
while ((*ptr) != '\0')
{
size++;
ptr++;
}
return size;
}
Last edited by Rahl; February 4th, 2009 at 06:54 PM.
Reason: clarity
You have to be careful with passing arrays to functions. As far as getSize is concerned array is a pointer to some number of ints. There is no way for this function to know how big the array is. It is impossible in C++.
I'm not sure why you are assigning the address of array[0] to another pointer. That is not really doing anything for you other than copying the address into another pointer variable. ptr is not an array at all. It is simply a pointer to an int.
Where is the calling function that fills the array? Is it being filled with a '\0' character? How?
Well, comparing to '\0' is a bit strange since it's an int array....why not just compare to 0?
But the bigger problem is that this isn't a function you should need. If an array is static-sized then you can hardcode it; if it's dynamic sized, then you should be tracking both its capacity and actual number of valid entries *explicitly* as you go rather than trying to determine them after the fact.
You have to be careful with passing arrays to functions. As far as getSize is concerned array is a pointer to some number of ints. There is no way for this function to know how big the array is. It is impossible in C++.
I was under the impression that every array automatically ends with the null terminator character, '\0' , so that when the computer walks through the array, it knows when to stop-- it sounds like that might not be entirely true (?) , although this member function does work with one digit arrays like
int array[]= {2,4,0,7,4,-3,8};
Originally Posted by kempofighter
I'm not sure why you are assigning the address of array[0] to another pointer. That is not really doing anything for you other than copying the address into another pointer variable. ptr is not an array at all. It is simply a pointer to an int.
I was concerned with side effects, but I realize now I can just make sure to use 'const' instead of using another variable.
I was under the impression that every array automatically ends with the null terminator character, '\0' , so that when the computer walks through the array, it knows when to stop-- it sounds like that might not be entirely true (?) , although this member function does work with one digit arrays like
int array[]= {2,4,0,7,4,-3,8};
Absolutely not true. Null-termination is only a factor with char arrays, and *then* only when you're using them to hold C-style strings. The null-terminator is enforced by the programmer (or the library functions like strcat), not by the language itself. Note that one consequence of this is that a char array of size n can only hold a string of length n-1, since one slot must be reserved for the NULL.
If you have an array arr of size n (either static or dynamic), you know *nothing* about what value will be at position arr[n]. It could be 0, it could be anything. You need to explicitly track the size yourself.
That, or just save yourself the trouble and use std::vector for all nontrivial arrays, and std::string for all such of those. They have a size() member function.
Last edited by Lindley; February 4th, 2009 at 09:50 PM.
The null-terminator is enforced by the programmer (or the library functions like strcat), not by the language itself.
I agree with everything else that you've said except for this.
C-style string semantics (i.e., implicit null-termination of string literals) are enforced at the language level.
I know you know this Lindley, but others might not.
Ah yes, in some cases that's true. Technically speaking though that's only the case for literals, which----strictly speaking----aren't quite the same as char arrays.
Ah yes, in some cases that's true. Technically speaking though that's only the case for literals, which----strictly speaking----aren't quite the same as char arrays.
I'll have to disagree. (Narrow) string literals have a type of const char[N].
If you know for certain that it is a stack allocated array object and not a pointer i.e. declared like
Code:
char arr1[15];
int arr2[32];
double arr3[80];
//etc...
and that it is not just a pointer to some block of memory (char*, int*, double*, etc.), then you can write a small template function that will tell you the size of the array. Something like this should do it:
The usage being something along the lines of (using the previously defined stack array code in this post):
Code:
std::cout << size(arr1) << std::endl; // prints 15
std::cout << size(arr2) << std::endl; // prints 32
std::cout << size(arr3) << std::endl; // prints 80
However, the above only works on stack allocated arrays, not pointers. If you have a char* pointer to some NULL termintated piece of memory, then you can get the size with this function:
If you have a pointer to any other type of array, then it is not wise to assume a termination condition even if you think you can control it, you should/must record the size of the array at it's creation time.
That said, I agree with the suggestion to use a proper container instead of arrays.
If you have a char* pointer to some NULL termintated piece of memory, then you can get the size with this function:
Code:
size_t size(std::string s)
{
return s.size();
}
Two problems with that: 1) Why not just use strlen()? The conditions where your function will work are identical to those where that will work, and it'll be more efficient pre-optimization. 2) It's not a good idea to introduce the notion of string length and array size being equivalent, because unless the programmer enforces that specifically, they usually aren't.
Two problems with that: 1) Why not just use strlen()? The conditions where your function will work are identical to those where that will work, and it'll be more efficient pre-optimization. 2) It's not a good idea to introduce the notion of string length and array size being equivalent, because unless the programmer enforces that specifically, they usually aren't.
True enough to both those points! I should have been clear that the code would only tell you the number of characters (excluding null terminators) in the passed char array and not the actual size of the array, which could be much bigger. Still the rest of the post counts.
Bookmarks