Variable-sized object may not be initialized - arrays

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.

Related

Static or Pointer When "Returning" Array

I'm attempting to load an array of size n (user input), with random values. I've read that you can not return an array in C, you must use a pointer (Which is quite confusing). However, I've read that if you are storing that array to a local variable in the returning function, a pointer will not work and a static array can be used (can that be returned in a function?). Also, I've read that you are supposed to call free after using the array is open the space back up? I must be using it wrong because it crashed. So I commented it out for now. Some clarification would be great.
Here's what I have so far. When printing, it's just printing what I'm assuming is just garbage.
int* prefixAverages1(int);
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
int choice;
int input;
printf("What is the size of the array?:");
scanf("%d", &input);
printf("Do you want to run prefixAverages 1 or 2?");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Beginning prefixAverages1\n");
int *a = prefixAverages1(input);
for (int i=0; i < input; i++) {
printf("%d", &i);
printf("%d \n", a[i]);
}
//free(a);
break;
}
}
int* prefixAverages1(int input) {
int x[input];
int *a = (int*)malloc(input);
srand(time(NULL));
for(int i = 0; i < input; i++) {
int s = 0;
for(int j = 0; j < i; j++) {
int r = rand() % 100;
x[j] = r;
s = s + x[j];
}
a[i] = s / (i+1);
printf("%d \n", a[i]);
}
return a;
}
I'm aware my syntax may be wonky. I haven't touched C in years, so let me know if my error is syntaxical.
edit: Values are printing as intended in the function. Added print statement in code for clairity
I'm attempting to load an array of size n (user input), with random
values. I've read that you can not return an array in C, you must use
a pointer (Which is quite confusing).
Yes, the relationship between pointers and arrays and the surprisingly wide scope of things you cannot do with arrays themselves are common points of confusion. To some extent it's a pedantic distinction. Almost everything C allows you to do with an array, it makes you do via a pointer, but it automatically converts values of array type to appropriate pointers, so that those details are largely hidden.
But in some places it pokes out. For example, there is no valid syntax that allows you even to try to declare a function that returns an array.
In other places it is actively misleading. For example, you can declare a function that appears to accept an array as an argument, but the standard explicitly specifies that the argument is actually a corresponding pointer (and that's what naturally falls out when you call such a function anyway). Specifically:
int foo(int x[3]);
is 100% equivalent to
int foo(int *x);
However, I've read that if you
are storing that array to a local variable in the returning function,
a pointer will not work
That's not so much about arrays specifically, but rather about automatic variables in general. These logically cease to exist when they go out of scope -- at the end of the innermost block in which they are declared -- so pointers to or into such objects are no longer valid once the function returns. One way to obtain such a pointer value is for the function to return it. That in itself is OK, but you cannot safely dereference such a pointer value.
and a static array can be used (can that be
returned in a function?).
The lifetime of static variables of any type is the whole execution of the program. Therefore, it is safe and can be meaningful to return a pointer (in)to a static variable from a function. But although it can work to return a pointer to a static array from your function, you still cannot return such an array itself.
Also, I've read that you are supposed to
call free after using the array is open the space back up?
You should free memory that you have allocated with one of the memory allocation functions (malloc() etc.), and no other. But when you allocate memory inside a function, you can give the caller responsibility for freeing that memory by returning the pointer to it, among other ways.
In fact, most of what you demonstrate in your example code is fine in those regards. However, you do make a key error that undermines your program. Here:
int *a = (int*)malloc(input);
You allocate input bytes and store the pointer to them in a, but that is not enough storage for input objects of type int. The size of an int varies from implementation to implementation, but the minimum size permitted by the standard is two bytes, in the most common size is four bytes. To allocate space for input objects of type int, the basic idiom is
int *a = malloc(input * sizeof(int));
Personally, though, I prefer
int *a = malloc(input * sizeof(*a));
because then I get the correct size no matter what type the pointer's referenced type is, and even if I change it later.
The fact that you treated the allocated space as if it were larger than it really was likely explains much of your program's misbehavior, including the crash when you tried to free the allocated memory.
First of all malloc takes an inparam of no of bytes not absolute array size - so change this line:-
int *a = (int*)malloc(input);
to
int *a = malloc(input*sizeof(int));
Secondly, to debug incorrect values being printed put a print in your function prefixAverages1 :-
...
...
a[i] = s / (i+1);
printf("%d \n", a[i]);
...
In main print, get rid of the first print.. this is probably making you think printing incorrect values.. The address of the local loop counter variable will look like garbage
printf("%d", &i);
OR if you wanted to track the indexes of the array elements as well modify it to :-
printf("%d", i);
You must introduce the free back to avoid leaking memory
And you should follow #AustinStephens's suggestion and avoid using a second function
This works as far as having a function that loads an array with random values:
void randomValues(int arr[], int size);
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
int i;
int input;
int *array;
printf("What is the size of the array?: ");
scanf("%d", &input);
array = malloc(sizeof(int) * input);
randomValues(array, input);
for(i = 0; i < input; ++i)
printf("array[%d] = %d\n", i, array[i]);
free(array);
return 0;
}
void randomValues(int arr[], int size) {
int i;
int r;
srand((int) time(0));
for(i = 0; i < size; ++i) {
r = rand() % 100;
arr[i] = r;
}
}

Let user choose size of array in C [duplicate]

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;

What is the exact meaning of defining `int *p={1,2,3};`?

I am trying to learn pointers in c.
As per my understanding int *p={1,2,3}; defines a pointer to the array of integers i.e {1,2,3}. So I deduct that p[0] is the first element of this array i.e 1. But my compiler(dev c++) is not giving any value and hanging for output.
How to find other elements of this array i.e 2 and 3 in terms of p? i.e is there any way to get these value through the pointer variable p. Please guide.
Sample program:
#include<stdio.h>
#include<conio.h>
main()
{
int *p={1,2,3};
printf("%d\n",p[0]);
getch();
}
Update: What about
int (*p)[3]={1,2,3};
int *p={1,2,3};
it is invalid C code. The right of = has to be a value of pointer type, not an initializer list of int elements.
Please enable all your compiler warnings and fix them.
int p[] = {1, 2, 3};
is valid C code. It initializes an array of 3 int elements.
#include <stdio.h>
#include <conio.h>
int main(){
int a[] = {1,2,3};
//int *p={1,2,3};//invalid
int *p1=(int[]){1,2,3};//valid in C99
printf("%d\n", p1[0]);//1
p1=a;
printf("%d\n", p1[0]);//1
//int (*p)[3]={1,2,3};//invalid
int (*p2)[3]=&(int[]){1,2,3};//valid in C99
printf("%d\n", (*p2)[0]);//1
p2 = &a;
printf("%d\n", (*p2)[0]);//1
getch();
return 0;
}
Yes,int (*p)[3] means pointer to array of 3 integers(My instructer also refers it as 2-dimensional pointer), in simple words it means that it can store address of the 1st row of a 2-Dimensional array,As you go on Increment the p it will point to the next subsequent row of the 2-D array, As demonstrated in below example.
int main(void)
{
int ary[2][3]={{1,2,3},{4,5,6}};
int (*p)[3]=ary;
printf("using ary: %d %d\n",p[0],p[1]); // outputs:2686708 2686720
printf("using ptr: %d %d\n",ary[0],ary[1]); //outputs:2686708 2686720
return 0;
}
And i think you are forgetting the basic property of pointers,They are used to store the address of other variables,You can't initialize pointers as you did in example,That is applicable only for strings,I feel you are trying to initialize integers pointers in the way of strings.
char *ptr="hello"; //correct
char *ptr[]={"hi","bye" } // correct
int *pttr=123; //Not Correct
int *pttr[]={{123},{456}} //Not Correct

Max number in array

I know many solutions exist for this one, but after looking around I haven't found any that involves pointers
Right now it keep throwing warnings and there's no output at all, what am I doing wrong?
#include <stdio.h>
int findbig (int a[], int n)
{
int max = a[0];
for (int i = 1; i < n; i++)
{
if (a[i] > max)
{
max = a[i];
}
}
return max;
}
int main (void)
{
int n;
printf("How many numbers? \n");
scanf("%d", &n);
int a[n];
printf("Now enter those %d numbers: \n", n);
for (int i = 1; i < n; i++)
{
scanf("%d", &a[i]);
}
int biggest = findbig (a[n], n);
printf("The biggest number is: %d\n", biggest);
return 0;
}
My compiler is complaining that:
-warning: passing argument 1 of 'findbig' makes pointer from integer without a cast [enabled by default]
-note: expected 'int *' but argument is of type 'int'
a[n] (as well as its equivalent *(a + n) form) is an int, not a pointer to int. It's also one past the boundary of your array. You need to turn your warnings into errors. You pass an int, whose value is converted to a pointer (address), which is, well, no good.
You need to call your function like so:
findbig(a, n);
Regardless of your signature, findbig receives a pointer to int. You cannot pass arrays to (or return them from) functions in C. They degrade to pointers to their first element.
On a side note, you're always skipping the first element when populating the array, so the user says "I want to enter N numbers", but you only allow them to enter n-1. The is also problematic as you use a[0] as your initial max number, but the value of that element is indeterminate.
It could be anything, i.e., some huge number, and then your function will give strange results. Either initialize the array to 0 (int a[n] = {0};) or start your loop at 0 (better).
By indexing a, doing a[n], you get the value of the array a in the n-th index, which is of int type. You need to invoke findbig(....); function using the array "pointer" variable, without indexing it, by doing:
findbig(a, n);
This line is wrong.
int a[n]
Array should be initialized with constant value, because the space of array is allocated before execution of the program. So, variables won't work.

How to get size of 2D array pointed by a double pointer?

I am trying to get the number of rows and columns of a 2D Array from a double pointer pointed to the array.
#include <stdio.h>
#include <stdlib.h>
void get_details(int **a)
{
int row = ??? // how get no. of rows
int column = ??? // how get no. of columns
printf("\n\n%d - %d", row,column);
}
Above function needs to print the details of the size, where am going wrong.
int main(int argc, char *argv[])
{
int n = atoi(argv[1]),i,j;
int **a =(int **)malloc(n*sizeof(int *)); // using a double pointer
for(i=0;i<n;i++)
a[i] = (int *)malloc(n*sizeof(int));
printf("\nEnter %d Elements",n*n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("\nEnter Element %dx%d : ",i,j);
scanf("%d",&a[i][j]);
}
get_details(a);
return 0;
}
I am using malloc to create the array.
What if I use something like this
column = sizeof(a)/sizeof(int) ?
C doesn't do reflection.
Pointers don't store any metadata to indicate the size of the area they point to; if all you have is the pointer, then there's no (portable) way to retrieve the number of rows or columns in the array.
You will either need to pass that information along with the pointer, or you will need to use a sentinel value in the array itself (similar to how C strings use a 0 terminator, although that only gives you the logical size of the string, which may be smaller than the physical size of the array it occupies).
In The Development of the C Programming Language, Dennis Ritchie explains that he wanted aggregate types like arrays and structs to not just represent abstract types, but to represent the collection of bits that would occupy memory or disk space; hence, no metadata within the type. That's information you're expected to track yourself.
void get_details(int **a)
{
int row = ??? // how get no. of rows
int column = ??? // how get no. of columns
printf("\n\n%d - %d", row,column);
}
I'm afraid you can't, as all you will get is the size of the pointer.
You need to pass the size of the array.
Change your signature to:
void get_details(int **a, int ROW, int COL)

Resources