Reputation: 11
I'm studying arrays in C, and I'm trying bubble-sort algorithm.
I do (in a main function):
int main{
srand(time(NULL)); //Randomize
int SIZE = (rand() % 20) + 1;
int number[ SIZE ] = { 0 };
...
}
But compiler says: variable-sized object may not be initialized
.
I need to declare an array to insert into it N randomly generated numbers, and then sort them by bubble-sort algorithm.
I use "stdio.h" and "time.h".
Why, if i try to initialize my array with all numbers to 0, compilers gives error?
If i erase = { 0 };
, compiler don't gives error, but programm works bad
This is my code: http://pastebin.com/uBaYWXbR
Thanks to all! :) Sorry if my english is bad.
Upvotes: 1
Views: 136
Reputation: 70999
There are different kinds of allocation.
One way is to declare the allocation within the source code. Then the compiler will create a variable (a name reference) in the object file, and make sure that the next name reference is far enough away in memory distance to guarantee that setting another variable won't write to the pre-allocated space of the array.
This cannot be done when the size of the array is not known at compile time. By using a variable, the size cannot be assured and the compiler cannot do the above calcuations.
You need to explicitly handle the allocation, because the only time the value of the calculated "element count" variable will be known is when the program run.
To do so, you ask the operating system to allocate some size. Note that this size is typically allocated on the heap, which is a memory area that the program is responsible for indicating when the memory is used and when the memory is freed. You will request the memory with
memset(number, 0, SIZE*sizeof(int));
which will return a number, called a pointer, which represents the address of the first element reserved by the memeset
command. It's type is
void *
Sometimes the star is moved around a bit, but keep in mind that it is part of the void. To read such types, read them from right-to-left, substituting the word "pointer" for the star.
(a pointer to no particular type)
Since you wanted a number of integers, you know that the allocated memory can contain integers, so cast the returned address to
(int *)
which represents a pointer to a number of integers.
int* number = (int*)malloc(SIZE*sizeof(int));
then you probably should zero out the memory, because if you will remember, you are now responsible for initialization as this is heap memory.
memset(number, 0, SIZE*sizeof(int));
which will write the byte '0' into all the bytes indicated by the byte-size of int multiplied by the number of int elements (SIZE) you requested.
Finally, you can now use allocated memory in a manner similar to what you would have done with int number[SIZE]. The syntax looks like
number[4] = 5;
or in more "pointer" oriented syntax
*(number + 4) = 5;
I highly recommend you use the array syntax exclusively until you eventually write something that is more concerned with the pointer than the values it points to. You can also read form the array using the syntax
int value = number[4];
or again, in the more pointer-oriented syntax
int value = *(number + 4);
keep in mind that you are fully in control here, if you assign a SIZE of 5, then only indexes {0,1,2,3,4} are valid. If you accidentally call number[12]
it is unclear what the program will do. If you are lucky it will crash, if you are unlucky it will mess up something else, making some other part of the program crash later or perhaps even not crashing but making some of the data in your program change inappropriately.
To release the memory, you then do
free(number);
Failure to release heap memory is known as a memory leak, and the problems with memory leaks are very difficult to fix, so it is a good programming practice to attempt to align your allocations with your frees in a single block of code, like so:
int function(... params ...) {
char* name = (char*)malloc(...);
... do stuff ....
free(name);
}
If you cannot do this, then it is probably because you have delayed your allocation till just before you need it
int caller(...) {
char* name = getName(...);
printf("%s", name);
// should name be freed?
}
a better strategy
int caller(...) {
char* name = (char*)malloc(getNameSize());
fillName(name);
printf("%s", name);
free(name);
}
Until you learn proper memory management and generally get the hang of using pointers, I suggest that you do not attempt to manipulate pointer values yet.
Upvotes: 1
Reputation: 311196
The error message is clear enough: you may not initialize VLA. So simply substitute this statement
int number[ SIZE ] = { 0 };
for
int number[ SIZE ];
If you want that all elements of the array would be equal to 0 then you can use standard C function memset
declared in header <string.h>
. For example
int number[ SIZE ];
memset( number, 0, sizeof( number ) );
Here is a complete example
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int main(void)
{
srand( ( unsigned int )time( NULL ) );
int SIZE = rand() % 20 + 1;
int a[SIZE];
memset( a, 0, sizeof( a ) );
return 0;
}
As for your program then even the first loop is invalid
for(i=0; i <= SIZE; i++);
{
number[ i ] = (rand() % 100) + 1;
}
First of all you have to remove the semicolon at the end of the for statement and the condition of the loop shall be
i < SIZE
Thus it will look as
for ( i = 0; i < SIZE; i++ )
{
number[ i ] = rand() % 100 + 1;
}
Also I have not seen where there is the bubble sorting in your program.:)
Upvotes: 5
Reputation: 6224
The size of number
isn't known at compile time, so the compiler cannot generate an initializer for it. You can initialize it yourself using memset
, or you can make the size of the array a compile-time constant.
memset(number, 0, SIZE*sizeof(int));
When you ommitted initialization altogether, your program probably failed because it was assuming that the array was initialized to 0, whereas it had not been initialized at all and contained arbitrary values.
Upvotes: 6