# Thread: array length question

1. It's not from a movie. It's from a paranoid mind.

Quzah.

2. Originally Posted by quzah
That's just nasty. Why would you index at -1? That's just begging for misuse. You should call your function "pleaseCrashMyApp".

Quzah.
it is what you encounter sometimes though, malloc implementations also use it a lot.
Although yeah you should put the alloc, size and free functionality their own functions and never ever use more than one of the systems in one project.

Code:
```int *alloc_array(size_t n)
{
int *arr = malloc(n+1);

if (arr)
{
*arr = n;
arr++;
}
return arr;
}

size_t arr_size(int *arr)
{
if (arr)
{
return arr[-1];
}
return 0;
}

void arr_free(int *arr)
{
if (arr)
free(arr-1);
}```
The -1 might scare you, but it really is a very much accepted method. return *(a-1) maybe?

3. Or just use iterators, dammit.

Code:
```void foo(int *start, int *end)
{
printf("Array length is %d\n", end - start);
}

int main(void)
{
int *ptr = malloc(100 * sizeof(int));
foo(ptr, ptr + 100);
}```

4. Originally Posted by jafet
Or just use iterators, dammit.

Code:
```void foo(int *start, int *end)
{
printf("Array length is %d\n", end - start);
}

int main(void)
{
int *ptr = malloc(100 * sizeof(int));
foo(ptr, ptr + 100);
}```
uhm the point is where to store the 100. if you call foo with ptr+100 the +100 is already the size, so foo is completely redundant On top of that if I'd call foo(ptr, ptr+50) the size would magically become 50 which is not correct

5. Originally Posted by Laserve
The -1 might scare you, but it really is a very much accepted method. return *(a-1) maybe?
No, it's a horrible method. What happens if you pass a string literal to the function? The point of this entire thread was that there is no way to tell the size of a block of allocated memory, other than an an array which has been defined in immediate scope. Otherwise, there is no way to do so. You can try to store it's length in one array member, but that doesn't work if you have say an array of characters 300 characters long, or a multitude of other examples I could come up with.

If you want to know the size of something, keep track of it in another variable, or simply pay attention to what you are doing.

Your idea is a horrible idea, because someone will end up using it to go:
Code:
`something = yourfunction( "what size is this?" );`
And they'll crash their program, and it's your fault. Or they'll pass an array, instead of "array + 1", which is stupid to have to do, and will have the same end result. Your code isn't even remotely close to being safe.

Quzah.

6. Originally Posted by quzah
Your idea is a horrible idea, because someone will end up using it to go:
Code:
`something = yourfunction( "what size is this?" );`
And they'll crash their program, and it's your fault. Or they'll pass an array, instead of "array + 1", which is stupid to have to do, and will have the same end result. Your code isn't even remotely close to being safe.

Quzah.
horrible is in your opinion of course.
I dont see many C coders say that it's the implementation's fault if they do

free("a constant string");

when malloc is implemented that it stores the size at first and returns a pointer 4 bytes further. It's just a matter of convention of knowing that you can only pass pointers allocated with malloc to free.

Same with the array size method, you have to let the others know that you can only pass pointers to arr_size that are allocated with alloc_array.
If an experienced C coder expects arr_size("string") to actually work I there's a much bigger problem than unsafe code

7. Why? What do you think strlen does? Arrays don't arrive at functions as arrays anyway. They arrive as pointers to their first element. So you passing an array is the same as me passing a string literal. They're identical upon arrival.

Quzah.

8. Originally Posted by quzah
Why? What do you think strlen does? Arrays don't arrive at functions as arrays anyway. They arrive as pointers to their first element. So you passing an array is the same as me passing a string literal. They're identical upon arrival.

Quzah.
Why what?
Why an experienced C programmer will not understand that arr_size "string" doesnt do what the function name implies?

For the same reason he should understand that passing a non zero terminated array to strlen causes undefined behaviour.
There is a convention that strlen expects a 0 at the end, why is that not considered dangerous by you then. You can still pass non zero terminated pointers to it. beginner programmers make the mistake all the time by forgetting to allocate space for the extra 0.
Its the same kind of idea as using the first bytes as length storage, only its stored at the beginning and not at the end.

Also, C libraries use things like this all the time. That they provide a function to allocate library objects and they obligate you to pass the returned pointers to a provided free function. So the -1 index is kept inside the imlpementation and the client programmer will never know this. If things do crash because he passed a pointer not returned from the alloc function its really the programmer's fault and not the library's

9. > For the same reason he should understand that passing a non zero terminated array to strlen causes undefined behaviour.
> There is a convention that strlen expects a 0 at the end, why is that not considered dangerous by you then.
It sounds like you think string literals aren't \0 terminated. They are.

> Also, C libraries use things like this all the time.
An example would solidify this argument somewhat, but even if you find one, it's merely your implementation and not indicative of everywhere.

10. Originally Posted by citizen
It sounds like you think string literals aren't \0 terminated. They are.
No I meant something like this:

Code:
```char buf [ ] = { '1', '2'};
strlen(buf);```
This will happily compile but you get undefined behaviour. it's the same thing as with array_sizes. strlen has no way to know if the array actually is zero terminated

Originally Posted by citizen
> Also, C libraries use things like this all the time.
An example would solidify this argument somewhat, but even if you find one, it's merely your implementation and not indicative of everywhere.

ok, an example from libxml (first thing I found with google)

Code:
```if (LIBXML(error_list) == NULL)
error_list = (zend_llist *) emalloc(sizeof(zend_llist));```
So would you try to pass error_list to standard library's free and expect it to work? I hope not. you use the libxml provided free function.

Same with an array size function. You can implement 3 functions for it. alloc_array/free_array and array_size. if a client programmer follows the convention that he only passes pointers returned from alloc_array to array_size and free_array there is no problem.

Popular pages Recent additions