I am writing C code and I would like to heap allocate 512*256 bytes. For my own convenience I would like to be able to access the elements with the syntax array[a][b]; no arithmetic to find the right index.
Every tutorial I see online tells me to create an array of pointers that point to arrays of the rows I want in my array. This means that each subarray needs to be malloc'd and free'd individually. I am interested in a solution that only requires one call to malloc and one call to free.(Thus all elements are contiguous) I think this is possible because I will not be constructing a jagged array.
I would appreciate if anyone could share the syntax for declaring such an array.
Well, if you want to allocate array of type, you assign it into a pointer of that type.
Since 2D arrays are arrays of arrays (in your case, an array of 512 arrays of 256 chars), you should assign it into a pointer to array of 256 chars:
char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
(The parentheses around *arr are to make it a pointer to array, and not an array of pointers)
If you allocate the array like this, it requires two calls to free, but it allows array[a][b] style syntax and is contiguous.
char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
array[i] = array[0] + (256 * i);
See array2 here for more information: http://c-faq.com/aryptr/dynmuldimary.html
This is easy assuming you don't need compatibility with the ancient C89 standard (among current C compilers, only MSVC and a few embedded-target compilers are that backwards). Here's how you do it:
int (*array)[cols] = malloc(rows * sizeof *array);
Then array[a][b] is valid for any a in [0,rows) and b in [0,cols).
In the language of the C standard, array has variably-modified type. If you want to pass the pointer to other functions, you'll need to repeat this type in the function argument list and make sure that at least the number of columns is passed to the function (since it's needed as part of the variably-modified type).
Edit: I missed the fact that OP only cares about a fixed size, 512x256. In that case, C89 will suffice, and all you need is:
int (*array)[256] = malloc(512 * sizeof *array);
The exact same type can be used in function argument lists if you need to pass the pointer around between functions (and also as a function return type, but for this use you might want to typedef it... :-)
Since you know the size of the array ahead of time, you could create a struct type that contains a 521x256 array, and then dynamically allocate the struct.
It is possible to dynamically allocate the same kind of multidimensional array that
static char x[512][256];
gives you, but it's a wee tricky because of type decay. I only know how to do it with a typedef:
typedef char row[512];
row *x = malloc(sizeof(row) * 256);
This only lets you determine the size of the second dimension at runtime. If both dimensions can vary at runtime, you need a dope vector.
If you know the size of the array, you can typedef it, and make a pointer to it. Here is a short snippet that demonstrates this use:
#include <stdio.h>
#include <stdlib.h>
typedef int array2d[20][20];
int main() {
int i,j;
array2d *a = malloc(sizeof(array2d));
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
(*a)[i][j] = i + j;
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
printf("%d ",(*a)[i][j]);
free(a);
return 0;
}
All great answers. I just have one thing to add for old weirdos like me who enjoy "retro" coding 16 bit with old compilers like Turbo C, on old machines. Variable length arrays are wonderful, but not needed.
char (*array)[81];
int lineCount;
/* Go get your lineCount.*/
lineCount = GetFileLines("text.fil");
array = malloc(lineCount * 81);
This is how we did "VLA" back in the olden days. It works exactly the same as
char (*array)[81] = malloc(lineCount * 81); /* error pre C99 */
without the luxury of VLA.
Just my old and tarnished 2 cents.
Related
This is well known code to compute array length in C:
sizeof(array)/sizeof(type)
But I can't seem to find out the length of the array passed as an argument to a function:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:
int length(const char**& array);
I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:
int main(int argc, char** argv);
Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.
sizeof only works to find the length of the array if you apply it to the original array.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
int a[5];
int * p = a;
sizeof(p); // :(
As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)
A second idea is storing the array length next to the array, just like any modern programming language does:
a -> [5];[0,0,0,0,0]
But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:
struct {
size_t length;
int * elements;
}
Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?
The array decays to a pointer when passed.
Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.
That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).
Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?
Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.
You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.
As stated by #Will, the decay happens during the parameter passing. One way to get around it is to pass the number of elements. To add onto this, you may find the _countof() macro useful - it does the equivalent of what you've done ;)
First, a better usage to compute number of elements when the actual array declaration is in scope is:
sizeof array / sizeof array[0]
This way you don't repeat the type name, which of course could change in the declaration and make you end up with an incorrect length computation. This is a typical case of don't repeat yourself.
Second, as a minor point, please note that sizeof is not a function, so the expression above doesn't need any parenthesis around the argument to sizeof.
Third, C doesn't have references so your usage of & in a declaration won't work.
I agree that the proper C solution is to pass the length (using the size_t type) as a separate argument, and use sizeof at the place the call is being made if the argument is a "real" array.
Note that often you work with memory returned by e.g. malloc(), and in those cases you never have a "true" array to compute the size off of, so designing the function to use an element count is more flexible.
Regarding int main():
According to the Standard, argv points to a NULL-terminated array (of pointers to null-terminated strings). (5.1.2.2.1:1).
That is, argv = (char **){ argv[0], ..., argv[argc - 1], 0 };.
Hence, size calculation is performed by a function which is a trivial modification of strlen().
argc is only there to make argv length calculation O(1).
The count-until-NULL method will NOT work for generic array input. You will need to manually specify size as a second argument.
This is a old question, and the OP seems to mix C++ and C in his intends/examples. In C, when you pass a array to a function, it's decayed to pointer. So, there is no way to pass the array size except by using a second argument in your function that stores the array size:
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
They are very few cases, where you don't need this, like when you're using multidimensional arrays:
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
Using the array notation in a function signature is still useful, for the developer, as it might be an help to tell how many elements your functions expects. For example:
void vec_add(float out[3], float in0[3], float in1[3])
is easier to understand than this one (although, nothing prevent accessing the 4th element in the function in both functions):
void vec_add(float * out, float * in0, float * in1)
If you were to use C++, then you can actually capture the array size and get what you expect:
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
In that case, the compiler will ensure that you're not adding a 4D vector with a 2D vector (which is not possible in C without passing the dimension of each dimension as arguments of the function). There will be as many instance of the vec_add function as the number of dimensions used for your vectors.
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
This works for me :)
length of an array(type int) with sizeof:
sizeof(array)/sizeof(int)
Best example is here
thanks #define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}
This is well known code to compute array length in C:
sizeof(array)/sizeof(type)
But I can't seem to find out the length of the array passed as an argument to a function:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:
int length(const char**& array);
I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:
int main(int argc, char** argv);
Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.
sizeof only works to find the length of the array if you apply it to the original array.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
int a[5];
int * p = a;
sizeof(p); // :(
As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)
A second idea is storing the array length next to the array, just like any modern programming language does:
a -> [5];[0,0,0,0,0]
But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:
struct {
size_t length;
int * elements;
}
Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?
The array decays to a pointer when passed.
Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.
That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).
Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?
Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.
You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.
As stated by #Will, the decay happens during the parameter passing. One way to get around it is to pass the number of elements. To add onto this, you may find the _countof() macro useful - it does the equivalent of what you've done ;)
First, a better usage to compute number of elements when the actual array declaration is in scope is:
sizeof array / sizeof array[0]
This way you don't repeat the type name, which of course could change in the declaration and make you end up with an incorrect length computation. This is a typical case of don't repeat yourself.
Second, as a minor point, please note that sizeof is not a function, so the expression above doesn't need any parenthesis around the argument to sizeof.
Third, C doesn't have references so your usage of & in a declaration won't work.
I agree that the proper C solution is to pass the length (using the size_t type) as a separate argument, and use sizeof at the place the call is being made if the argument is a "real" array.
Note that often you work with memory returned by e.g. malloc(), and in those cases you never have a "true" array to compute the size off of, so designing the function to use an element count is more flexible.
Regarding int main():
According to the Standard, argv points to a NULL-terminated array (of pointers to null-terminated strings). (5.1.2.2.1:1).
That is, argv = (char **){ argv[0], ..., argv[argc - 1], 0 };.
Hence, size calculation is performed by a function which is a trivial modification of strlen().
argc is only there to make argv length calculation O(1).
The count-until-NULL method will NOT work for generic array input. You will need to manually specify size as a second argument.
This is a old question, and the OP seems to mix C++ and C in his intends/examples. In C, when you pass a array to a function, it's decayed to pointer. So, there is no way to pass the array size except by using a second argument in your function that stores the array size:
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
They are very few cases, where you don't need this, like when you're using multidimensional arrays:
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
Using the array notation in a function signature is still useful, for the developer, as it might be an help to tell how many elements your functions expects. For example:
void vec_add(float out[3], float in0[3], float in1[3])
is easier to understand than this one (although, nothing prevent accessing the 4th element in the function in both functions):
void vec_add(float * out, float * in0, float * in1)
If you were to use C++, then you can actually capture the array size and get what you expect:
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
In that case, the compiler will ensure that you're not adding a 4D vector with a 2D vector (which is not possible in C without passing the dimension of each dimension as arguments of the function). There will be as many instance of the vec_add function as the number of dimensions used for your vectors.
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
This works for me :)
length of an array(type int) with sizeof:
sizeof(array)/sizeof(int)
Best example is here
thanks #define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}
I would like to read 2 numbers n,m from text file and then allocate a 2D array with n rows and m columns.
Also, I would like to initialise the array in my main function in order to use it later in other functions, and do the reading and allocating in a different function, which I will call from the main function.
I know how to handle the reading, but I'm struggling with the array allocation.
I've read quite a few answer to similar questions here, but they didn't help me.
I've wrote the following code, but not sure how to continue with it to get the desired result:
void func(int** array, int* rows, int* cols){
int n, m;
FILE *file;
fp = fopen("test.txt", "r");
if (file) {
/* reading numbers n and m */
*rows = n;
*cols = m;
**array = (int*)malloc(n * m * sizeof(int));
fclose(file);
}
}
int main() {
int rows, cols;
int** array;
func(&array, &rows, &cols);
return 0;
}
I thought perhaps I should first allocate a 2D array with calloc and then use realloc after reading n,m, but not sure if that's the best practise.
What is the best practise to allocate a 2D array based on dimensions I read from text file?
First the biggest goofs here:
Your function doesn't have any types in the function signature -- this should be rejected by the compiler
a 2D array is not the same as an array of pointers
what should && mean? & is the address of something, its result can't have an address because it isn't stored anywhere, so this doesn't make sense
If you want to dynamically allocate a real 2D array, you need to either have the second dimension fixed or use VLAs (which are optional in C11, but assuming support is quite safe) with a variable. Something like this:
// dimensions in `x` and `y`, should be of type `size_t`
int (*arr)[x] = malloc(y * sizeof *arr);
In any case, the second dimension is part of the type, so your structure won't work -- the calling code has to know this second dimension for passing a valid pointer.
Hint: This first part doesn't apply to the question any more, OP forgot to mention he's interested in C90 only. I added the appropriate tag, but leave the upper part of the answer for reference. The following applies to C90 as well:
You write int ** in your code, this would be a pointer to a pointer. You can create something that can be used like a 2D array by using a pointer to a pointer, but then, you can't allocate it as a single chunk.
The outer pointer will point to an array of pointers (say, the "row-pointers"), so for each of these pointers, you have to allocate an array of the actual values. This could look like the following:
// dimensions again `x` and `y`
int **arr = malloc(y * sizeof *arr);
for (size_t i = 0; i < y; ++i)
{
arr[i] = malloc(x * sizeof **arr);
}
Note on both snippets these are minimal examples. For real code, you have to check the return value of malloc() each time. It could return a null pointer on failure.
If you want to have a contiguous block of memory in the absence of VLAs, there's finally the option to just use a regular array and calculate indices yourself, something like:
int *arr = malloc(x * y * sizeof *arr);
// access arr[8][15] when x is the second dimension:
arr[x*8 + 15] = 24;
This will generate (roughly) the same executable code as a real 2D array, but of course doesn't look that nice in your source.
Note this is not much more than a direct answer to your immediate question. Your code contains more goofs. You should really enable a sensible set of compiler warnings (e.g. with gcc or clang, use -Wall -Wextra -pedantic -std=c11 flags) and then fix each and every warning you get when you move on with your project.
I am writing C code and I would like to heap allocate 512*256 bytes. For my own convenience I would like to be able to access the elements with the syntax array[a][b]; no arithmetic to find the right index.
Every tutorial I see online tells me to create an array of pointers that point to arrays of the rows I want in my array. This means that each subarray needs to be malloc'd and free'd individually. I am interested in a solution that only requires one call to malloc and one call to free.(Thus all elements are contiguous) I think this is possible because I will not be constructing a jagged array.
I would appreciate if anyone could share the syntax for declaring such an array.
Well, if you want to allocate array of type, you assign it into a pointer of that type.
Since 2D arrays are arrays of arrays (in your case, an array of 512 arrays of 256 chars), you should assign it into a pointer to array of 256 chars:
char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
(The parentheses around *arr are to make it a pointer to array, and not an array of pointers)
If you allocate the array like this, it requires two calls to free, but it allows array[a][b] style syntax and is contiguous.
char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
array[i] = array[0] + (256 * i);
See array2 here for more information: http://c-faq.com/aryptr/dynmuldimary.html
This is easy assuming you don't need compatibility with the ancient C89 standard (among current C compilers, only MSVC and a few embedded-target compilers are that backwards). Here's how you do it:
int (*array)[cols] = malloc(rows * sizeof *array);
Then array[a][b] is valid for any a in [0,rows) and b in [0,cols).
In the language of the C standard, array has variably-modified type. If you want to pass the pointer to other functions, you'll need to repeat this type in the function argument list and make sure that at least the number of columns is passed to the function (since it's needed as part of the variably-modified type).
Edit: I missed the fact that OP only cares about a fixed size, 512x256. In that case, C89 will suffice, and all you need is:
int (*array)[256] = malloc(512 * sizeof *array);
The exact same type can be used in function argument lists if you need to pass the pointer around between functions (and also as a function return type, but for this use you might want to typedef it... :-)
Since you know the size of the array ahead of time, you could create a struct type that contains a 521x256 array, and then dynamically allocate the struct.
It is possible to dynamically allocate the same kind of multidimensional array that
static char x[512][256];
gives you, but it's a wee tricky because of type decay. I only know how to do it with a typedef:
typedef char row[512];
row *x = malloc(sizeof(row) * 256);
This only lets you determine the size of the second dimension at runtime. If both dimensions can vary at runtime, you need a dope vector.
If you know the size of the array, you can typedef it, and make a pointer to it. Here is a short snippet that demonstrates this use:
#include <stdio.h>
#include <stdlib.h>
typedef int array2d[20][20];
int main() {
int i,j;
array2d *a = malloc(sizeof(array2d));
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
(*a)[i][j] = i + j;
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
printf("%d ",(*a)[i][j]);
free(a);
return 0;
}
All great answers. I just have one thing to add for old weirdos like me who enjoy "retro" coding 16 bit with old compilers like Turbo C, on old machines. Variable length arrays are wonderful, but not needed.
char (*array)[81];
int lineCount;
/* Go get your lineCount.*/
lineCount = GetFileLines("text.fil");
array = malloc(lineCount * 81);
This is how we did "VLA" back in the olden days. It works exactly the same as
char (*array)[81] = malloc(lineCount * 81); /* error pre C99 */
without the luxury of VLA.
Just my old and tarnished 2 cents.
This is well known code to compute array length in C:
sizeof(array)/sizeof(type)
But I can't seem to find out the length of the array passed as an argument to a function:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:
int length(const char**& array);
I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:
int main(int argc, char** argv);
Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.
sizeof only works to find the length of the array if you apply it to the original array.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
int a[5];
int * p = a;
sizeof(p); // :(
As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)
A second idea is storing the array length next to the array, just like any modern programming language does:
a -> [5];[0,0,0,0,0]
But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:
struct {
size_t length;
int * elements;
}
Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?
The array decays to a pointer when passed.
Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.
That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).
Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?
Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.
You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.
As stated by #Will, the decay happens during the parameter passing. One way to get around it is to pass the number of elements. To add onto this, you may find the _countof() macro useful - it does the equivalent of what you've done ;)
First, a better usage to compute number of elements when the actual array declaration is in scope is:
sizeof array / sizeof array[0]
This way you don't repeat the type name, which of course could change in the declaration and make you end up with an incorrect length computation. This is a typical case of don't repeat yourself.
Second, as a minor point, please note that sizeof is not a function, so the expression above doesn't need any parenthesis around the argument to sizeof.
Third, C doesn't have references so your usage of & in a declaration won't work.
I agree that the proper C solution is to pass the length (using the size_t type) as a separate argument, and use sizeof at the place the call is being made if the argument is a "real" array.
Note that often you work with memory returned by e.g. malloc(), and in those cases you never have a "true" array to compute the size off of, so designing the function to use an element count is more flexible.
Regarding int main():
According to the Standard, argv points to a NULL-terminated array (of pointers to null-terminated strings). (5.1.2.2.1:1).
That is, argv = (char **){ argv[0], ..., argv[argc - 1], 0 };.
Hence, size calculation is performed by a function which is a trivial modification of strlen().
argc is only there to make argv length calculation O(1).
The count-until-NULL method will NOT work for generic array input. You will need to manually specify size as a second argument.
This is a old question, and the OP seems to mix C++ and C in his intends/examples. In C, when you pass a array to a function, it's decayed to pointer. So, there is no way to pass the array size except by using a second argument in your function that stores the array size:
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
They are very few cases, where you don't need this, like when you're using multidimensional arrays:
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
Using the array notation in a function signature is still useful, for the developer, as it might be an help to tell how many elements your functions expects. For example:
void vec_add(float out[3], float in0[3], float in1[3])
is easier to understand than this one (although, nothing prevent accessing the 4th element in the function in both functions):
void vec_add(float * out, float * in0, float * in1)
If you were to use C++, then you can actually capture the array size and get what you expect:
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
In that case, the compiler will ensure that you're not adding a 4D vector with a 2D vector (which is not possible in C without passing the dimension of each dimension as arguments of the function). There will be as many instance of the vec_add function as the number of dimensions used for your vectors.
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
This works for me :)
length of an array(type int) with sizeof:
sizeof(array)/sizeof(int)
Best example is here
thanks #define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}