Piero
Piero

Reputation: 11

Declaration with array, C

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

Answers (3)

Edwin Buck
Edwin Buck

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

Vlad from Moscow
Vlad from Moscow

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 memsetdeclared 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

user3553031
user3553031

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

Related Questions