Let user choose size of array in C [duplicate] - c

This question already has answers here:
Initializing variable length array [duplicate]
(3 answers)
Closed 8 years ago.
I need to let the user enter an integer N which will become the size of the array. I tired the following:
int N;
printf("Please enter size of array\n");
scanf("%d", &N);
int a[N] = {0};
However i get the following error when I do this:
error: variable-sized object may not be initialized
Anyone know how can do this? Any help would be greatly appreciated!

You need to use a dynamically allocated array.
int N;
printf("Please enter size of array\n");
scanf("%d", &N);
int *a = malloc(N * sizeof(int));
Then you can access it like a normal array.
Edit: in C99 the compiler allows dynamic length arrays, so you can just use memset or do a for loop going through the array and setting the value for each index

You may not initialize variable length arrays.
From the C Standard (6.7.9 Initialization)
3 The type of the entity to be initialized shall be an array of
unknown size or a complete object type that is not a variable length
array type.
So write simply
int a[N];
instead of
int a[N] = {0};
If you need to initialize the array with zeroes then you can use standard function memset declared in header <string.h>
#include <string.h>
//...
memset( a, 0, sizeof( a ) );

Just like the error says: you may not initialize a variable sized object (like that). You need to either set the individual elements in a loop, or use memset:
for(size_t i = 0; i < N; i++){
a[i] = 0;
}
or:
memset(a, 0, sizeof a);
Note that memset requires you to include <string.h>
EDIT: sizeof a is shorter and looks better :)

Try this:
int N;
printf("Please enter size of array\n");
scanf("%d", &N);
int a[N];
a[0] = 0;

Related

Variable-sized object may not be initialized

In line 6 it appears that int variable-sized object may not be initialized, what is the problem with the int? How can i fix it?
#include <stdio.h>
int main (void)
{
const int SIZE=5;
//variable remain constant
int grades[SIZE]= {66,50,93,67,100};
double sum= 0.0;
int i;
printf("\nMy grades are:\n");
for (i=0;i<SIZE;i++)//0 first character and < because last character is sentinel
printf("%d\t",grades[i]);
printf("\n\n");
for (i=0;i<SIZE;i++) //analyze data in list and retrieve it
sum=sum+grades[i];
printf("My average is %.2f\n\n",sum/SIZE); //sum /size for average with decimals
return 0;
}
I expected to find an average using simple one-dimensional array, but that problem doesn't let me run the program
SIZE is not a constant.
SIZE is a const int, but, as strange as it sounds, it is still not a constant. grades[SIZE] is a variable length array. Variable length arrays may not be initialized. *1
const int SIZE=5;
int grades[SIZE]= {66,50,93,67,100};// error: variable-sized object may not be initialized
Alternate 1: Use a constant
5 is a constant of type int.
#define SIZE 5
int grades[SIZE]= {66,50,93,67,100};
Alternate 2: Promptly assign
Assign or copy in the values from some source, perhaps from a compound literal.
const int SIZE=5;
int grades[SIZE];
v-----------------------v compound literal
memcpy(grades, (int []){66,50,93,67,100}, sizeof grades);
*1
Perhaps a future version of C will allow this.

Compile error: storage size of 'arr' isn't constant [duplicate]

This question already has answers here:
why "storage size of 'array' isn't constant"
(3 answers)
Closed 7 months ago.
I have a problem in this code.
This gives:
storage size of 'arr' isn't constant
int static arr[size];"
Code:
#include<stdio.h>
int* func( int size );
void main (){
int*res ;
int len =5 ;
res=func(len);
for(int i=0 ;i<len;++i){
printf("The Element %d is \n",i,*(res+i));
}
}
int* func( int size ){
int static arr[size];
for(int i=0 ;i<size;++i){
printf("Enter %d \n",i);
scanf("%d",&arr[i]);
}
return arr ;
}
Why? How can I fix it?
You can't declare a variable-length array as static.
Objects with static storage duration are allocated when the program is first loaded; arr will be allocated before func is ever called. For this to work, arr's size has to be known at compile time.
Unfortunately, you using the parameter size when you declare the array, whose size isn't known until runtime; this makes it a variable-length array.
So, this isn't going to work the way you want - you'll probably want to use the malloc or calloc library functions instead.

Can I assign an array to a dynamically created array (using pointers) the way you would normally initialize an array[]?

I tried this following code but it clearly didn't work:
void main3()
{
int n;
printf("Input the dimension of the array");
scanf("%d", &n);
int* testMatrix2 = malloc(sizeof(int) * n);
testMatrix2 = {512, 51, 642}; //is there a way to do this? "expected an expression" error
}
As the comment shows, is there a way to initialize an array as you would normally do without using arrays? I know it's a risky move, but it would make my life easier during testing.
The use of for cycles would not be feasible for me as I need a sort of randomness in the array.
As #EugeneSh. stated it is not possible for any size array. If the array has a fixed size you can wrap it into the structure:
typedef struct
{
int x[10];
}wrappedArray;
void foo(void)
{
wrappedArray *wa = malloc(sizeof(*wa));
*wa = (wrappedArray){1,2,3,4,5,6,7,8,9,10};
}
Arrays are "non-modifiable" L-values. Therefore they cannot be assigned with = operator.
However, you could memcpy from a compound literal.
memcpy(testMatrix2, (const int[]){512, 51, 642}, sizeof(int[3]));
Just ensure that n >= 3 before doing this to avoid Undefined Behavior.
As the other post already shown how to copy array to dynamically allocated space. Just in case if you don't need to access the array in some other function (or out of scope), then no need to allocate space dynamically. You can use compound literal:
#include <stdio.h>
int main (void) {
int* testMatrix2 = (int []){512, 51, 642};
for (int i = 0; i < 3; ++i) {
printf ("%d ", testMatrix2[i]);
}
printf ("\n");
return 0;
}
Output:
# ./a.out
512 51 642
Compound literals Constructs an unnamed object of specified type in-place.
In this statement of above program
int* testMatrix2 = (int []){512, 51, 642};
(int []){512, 51, 642} is a compound literal. It will create an unnamed automatic array of type int [3], initialise the array to the value 512, 51 and 642 and the pointer to first element of this array object will be assigned to testMatrix2.

How to create an array of arrays in C when the number of subarrays is not specified? [duplicate]

This question already has answers here:
Can you define the size of an array at runtime in C
(10 answers)
C dynamically growing array
(10 answers)
Closed 2 years ago.
I am trying to create an array of arrays but the the number of subarrays is unknown.
Jagged array is array of arrays such that member arrays can be of different sizes, i.e., we can create a 2-D array but with a variable number of columns in each row.
Static Jagged Array:
int kk0[4] = { 1, 2, 3, 4 };
int kk1[2] = { 5, 6 };
int* jagged[2] = { kk0, kk1 };
Dynamic Jagged Array:
int* jagged[2];
jagged[0] = malloc(sizeof(int) * 1);
jagged[1] = malloc(sizeof(int) * 3);
Reference : https://en.wikipedia.org/wiki/Jagged_array
If the number of sub arrays is not known then the array must be expandable when there are more sub arrays than you thought.
int **myArrays; // the array of arrays
int nSubArrays= 0; // its current size
int nUsed= 0; // how many have been used
#define INCREMENT 5 // increment for alocation
myArrays= malloc(sizeof(int *) * INCREMENT);
nSubArrays= INCREMENT;
nUsed= 0;
now fill the array(s):
myArrays[nUsed]= fillSubArray();
nUsed++;
and expand the array when it becomes full:
if (nUsed==nSubArrays) {
int **tmp= realloc(myArrays, sizeof(int *)*(nSubArrays+INCREMENT));
if (!tmp) return 0; // error
myArrays= tmp;
nSubArrays += INCREMENT;
"create an array of arrays but the the number of subarrays is unknown."
If using C99, or a compiler since then that supports variable length arrays (optional since C11), this would provide a way to do this at run-time. A short example:
#define ARRAY_BASE_SIZE 20 //known at compile time
int main()
{
int numSubArrays = 0;
printf("enter a value for number of sub-arrays:\n");
int count = scanf("%d", &numSubArrays);//not known until run-time
if(count == 1)
{
int array[ARRAY_BASE_SIZE][numSubArrays];
memset(array, 0, sizeof(array));
}
return 0;
}
How about this, its just an attempt to give a start point, not the complete answer, but we can build on this.
Also we need to keep track of size of each subarray to access valid locations, am sure that can be done easily by some kind of book keeping.
#include <stdio.h>
#include <stdlib.h>
#define BASE_SIZE 3
int main()
{
int** dyn_array = NULL;
int countSubArray = 0;
int count = 0;
int size = 0;
dyn_array = malloc(sizeof (int* ) * BASE_SIZE);
if ( dyn_array ) {
printf("enter number of subarrays:");
scanf("%d", &countSubArray);
while( count < countSubArray) {
printf("enter sizeof %d subarray", count+1);
scanf("%d", &size);
if ( dyn_array[count] = malloc(sizeof (int) * size) )
{
printf("Allocated sub array %d at %p\n",count+1, (void*) dyn_array[count]);
}
count++;
}
}
return 0;
}
In C it is very common practice to declare a pointer and reference it as an array. In C an array will decay to a pointer when the reference of the array is assigned to the pointer. To reference an array of arrays, it is common to declare a pointer-to-pointer, assign it to the reference of a 2-D array, and later index it like a 2-D array.
The following are all equivalent. argv is an array of array of char. Using [] makes your intention of using indexing a pointer as an array clear to other programmers who might be reading your code.
char **argv;
char *argv[];
char argv[][]; (this is wrong)
The size of the array is usually communicated separately. In fact, the parameters of the main function does just that. When you see
int main(int argc, char *argv[]);
The char *argv[] is an array of array of characters (aka array of strings) passed from the command line. The argument argc represents the number of arrays in argv. To index the first element in the array, use argv[0], whose type is will be char* (aka char[]).

c sizeof function of an array in a function is always four bytes despite the number of array elements [duplicate]

This question already has answers here:
"sizeof" to know the size of an array doesn't work in a function in C [duplicate]
(2 answers)
Closed 6 years ago.
When I print the (size of the array/size of the the first element), I get the right answer, but when I do the same thing in the function, I get the size of the array to be four and the size of the first element of the array to be four hence the division is always one.
#include<stdio.h>
int sizer(int *);
int main()
{
int num;
printf("Please an index: ");
scanf("%d",&num);
int array[num];
int size = sizer(array); //function to calculate array length
/*answer is always 4*/
printf("%d\n", size);
/*answer is correct*/
printf("%d\n", sizeof(array) / sizeof(array[0]));
return 0;
}
/*function to calculate array length*/
int sizer(int *array)
{
return sizeof(array) / sizeof(array[0]);
}
sizeof is not a function called at runtime, even though it looks like one. It is a feature of the compiler. It looks at a data object and replaces the sizeof() expression with a constant.
int arr[10];
int size = sizeof(arr)/sizeof(int);
This works because the compielr can see how big arr is. arr is a statically sized array here. Both sizeof expressions are replaced with the appropriate values.
int arr[10];
int size = sizer(arr);
....
int sizer(int array[]) {
return (sizeof(array)/sizeof(int));
}
This doesn't work. In sizer, array looks like an array but arrays passed in as parameters are actually just pointers to the array type. So sizeof(array) is equivalent to sizeof(int *)
scanf("%d",&num);
int arr[num];
int size1 = sizeof(arr)/sizeof(int);
int size2 = sizer(arr);
....
int sizer(int array[]) {
return (sizeof(array)/sizeof(int));
}
Here, size1 works but size2 doesn't. The creation of arr is actually allocated like this:
int arr_sizeof = sizeof(int)*num;
int *arr = alloca(arr_sizeof);
Then later on, sizeof(arr) is quietly replaced with arr_sizeof. But the compiler can only do this in the same scope that arr is created, because when arr is passed to sizer it's just converted to an int * again, so the size information is not carried over. sizer fails for thet same reason, arrays in function parameters are just passed along as simple pointers.
When you pass an array to a function you are really just passing a pointer to the first element, so in the body of sizer, the parameter array is just a pointer to int. Your function correctly returns sizeof(int*)/sizeof(int) (which is 2 rather than 4 on my machine), though this is probably not what you want. There really isn't any way for a function in C to compute the length of a passed array, which is why it is standard in C to pass the number of elements in an array as one of the parameters in any function which takes an array parameter.

Resources