By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,682 Members | 1,071 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,682 IT Pros & Developers. It's quick & easy.

Variable length array confusion

P: n/a
Hai,
I studied that the array size is fixed. But I come across a word
called "variable length array". Is it possible to change the array
size? So I tried the following:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
printf("%d\n",y[i]);
return 0;
}

This is a wrong one and given me a runtime error.

Then what is variable length array?

So I tried the following:

int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
{
*y = malloc(sizeof *y);
if(*y == NULL)
exit(EXIT_FAILURE);
else
printf("%d size=%d\n",y[i],sizeof y);

}
return 0;
}

OUTPUT:

589600 size=12
9 size=12
10 size=12
0 size=12
0 size=12
0 size=12
588632 size=12
11912 size=12
1 size=12
589584 size=12
593160 size=12
…....
…....
….....
…
Even though it gave some warning and runtime error I can see the array
size has changed since I used malloc and allocated with 3 * 4 (C array
starts with zero) so the size = 12.

1)Is my understanding of the above is correct?

2)Is the above program behavior is undefined?

Kindly help.
Nov 13 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

<da***********@yahoo.com> schrieb im Newsbeitrag
news:a3**************************@posting.google.c om...
Hai,
I studied that the array size is fixed. But I come across a word
called "variable length array". Is it possible to change the array
size? So I tried the following:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
printf("%d\n",y[i]);
return 0;
}

This is a wrong one and given me a runtime error.

Then what is variable length array?


Here is an example
(assuming you have no C99 compiler)

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int i;
void *tmp;
int *y = malloc(20 * sizeof *y);

if(y)
{
y[0] = 7;
y[1] = 9;
y[2] = 10;
for(i = 3; i < 20; i++)
{
y[i] = 0;
}
for(i = 0; i < 20; i++)
{
printf("%d ", y[i]);
}
printf("\n");
tmp = realloc(y, 25 * sizeof *y);
if(tmp)
{
y = tmp;
for(i = 3; i < 25; i++)
{
y[i] = i;
}
for(i = 0; i < 25; i++)
{
printf("%d ", y[i]);
}
printf("\n");
}
free(y);
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}

Robert
Nov 13 '05 #2

P: n/a
da***********@yahoo.com wrote:
I studied that the array size is fixed. But I come across a word
called "variable length array". Is it possible to change the array
size? So I tried the following:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
You also need to initialize i, the way you use it here it will have
some completely random value. Only static and global variables are
initialized to 0.
printf("%d\n",y[i]);
return 0;
} This is a wrong one and given me a runtime error.
Yes, because you're trying to access non-existent elements of the array
'y'. Everything after y[2] does not belong to you.
Then what is variable length array? So I tried the following: int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
Again, you need to initialize i, use e.g.
for ( i = 0; i < 20; i++ )
{
*y = malloc(sizeof *y);
Here you allocate memory for a single integer and assign the address
you get back from malloc() to the first element of the array 'y',
thereby implicitely converting the address to an integer (note that
writing *y is the same as y[0] because y[i] is always the same as
*(y+i)). And, of course, that's nothing you should be doing and the
compiler should emit a warning, at least if you have raised the
warning level to something useful.
if(*y == NULL)
exit(EXIT_FAILURE);
else
printf("%d size=%d\n",y[i],sizeof y);
Here you still run into the same problem as in your first program, you
read past the last element of the 'y' array. Just having allocated some
memory and assigned the address to the first element of the array doesn't
change anything. And 'sizeof y' will always be 12 because that's the
amount of memory taken by the array 'y' (you seem to run this on a
machine where siezof(int) is 4). You can't change the size of 'y' by
allocation, it's fixed the moment you compiled the program.
}
return 0;
}


There are two things you seem to be confusing, variable length arrays
and dynamically allocated arrays. Variable length arrays are a feature
that has been introduced in (standard) C only with the new C99 standard
and not all compilers support it yet. It means arrays of a length that
hasn't been compiled in as a fixed number into the program but is only
calculated during runtime. E.g. you can have a function like this

void vla( int n )
{
int x[ n ];
int i;

for ( i = 0; i < n; i++ )
x[ i ] = i;
}

This wasn't allowed with C89 (but some compilers did allow it as an
extension, e.g. gcc) and which only a C99 compliant compiler must
support.

On the other had you have dynamically allocated arrays:

void daa( int n )
{
int *x;
int i;

x = malloc( n * sizepf *x );
if ( x == NULL )
{
fprintf( stderr, "Can't allocate memory\n" );
exit( EXIT_FAILURE );
}

for ( i = 0; i < n; i++ )
x[ i ] = i;

free( x );
}

This is legal even with C89. Of course 'x' isn't a real array but just
a pointer to some memory that can hold the number of integers you need.
And in many places 'x' can be treated like a real array, but there are
subtle differences, e.g. sizeof x is not the amount of memory it's
pointing to but the size of a pointer. And, of course, you must free()
the memory you allocated when you don't need it anymore.

Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring
Nov 13 '05 #3

P: n/a
On 29 Sep 2003 06:00:42 -0700, in comp.lang.c ,
da***********@yahoo.com wrote:
Hai,
I studied that the array size is fixed. But I come across a word
called "variable length array".
A variable length array is one whose length is a variable !!

In old C, you had to declare variables with a constant as the length
double foo[56];

in new C you can declare them using a variable
int bar = 56;
double foo[bar];

This is obviously handy if bar were a parameter to some function that
needed a bar-sized array of doubles.
Is it possible to change the array
size?


Once you create it, its fixed. (Note that malloc doesn't create
arrays, although malloc'ed memory can be treated as an array to all
intents and purposes, which of course begs the question "whats the
point of VLAs then?")

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
Nov 13 '05 #4

P: n/a
Je***********@physik.fu-berlin.de wrote in message news:<bl************@uni-berlin.de>...
da***********@yahoo.com wrote:
I studied that the array size is fixed. But I come across a word
called "variable length array". Is it possible to change the array
size? So I tried the following:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)
You also need to initialize i, the way you use it here it will have
some completely random value. Only static and global variables are
initialized to 0.
printf("%d\n",y[i]);
return 0;
}

This is a wrong one and given me a runtime error.


Yes, because you're trying to access non-existent elements of the array
'y'. Everything after y[2] does not belong to you.
Then what is variable length array?

So I tried the following:

int main(void)
{
int y[3] = { 7, 9,10},i;
for (;i<20;i++)


Again, you need to initialize i, use e.g.
for ( i = 0; i < 20; i++ )
{
*y = malloc(sizeof *y);


Here you allocate memory for a single integer and assign the address
you get back from malloc() to the first element of the array 'y',
thereby implicitely converting the address to an integer (note that
writing *y is the same as y[0] because y[i] is always the same as
*(y+i)). And, of course, that's nothing you should be doing and the
compiler should emit a warning, at least if you have raised the
warning level to something useful.

^^^^^^^^^^^^^^^

Yes , gcc –Wall –o temp temp.c
Gives me warning about the assignment.

if(*y == NULL)
exit(EXIT_FAILURE);
else
printf("%d size=%d\n",y[i],sizeof y);
Here you still run into the same problem as in your first program, you
read past the last element of the 'y' array. Just having allocated some
memory and assigned the address to the first element of the array doesn't
change anything. And 'sizeof y' will always be 12 because that's the
amount of memory taken by the array 'y' (you seem to run this on a
machine where siezof(int) is 4). You can't change the size of 'y' by
allocation, it's fixed the moment you compiled the program.
}
return 0;
}


There are two things you seem to be confusing, variable length arrays
and dynamically allocated arrays. Variable length arrays are a feature
that has been introduced in (standard) C only with the new C99 standard
and not all compilers support it yet. It means arrays of a length that
hasn't been compiled in as a fixed number into the program but is only
calculated during runtime. E.g. you can have a function like this

void vla( int n )
{
int x[ n ];
int i;

for ( i = 0; i < n; i++ )
x[ i ] = i;
}

This wasn't allowed with C89 (but some compilers did allow it as an
extension, e.g. gcc) and which only a C99 compliant compiler must
support.

On the other had you have dynamically allocated arrays:

void daa( int n )
{
int *x;
int i;

x = malloc( n * sizepf *x );
if ( x == NULL )
{
fprintf( stderr, "Can't allocate memory\n" );
exit( EXIT_FAILURE );
}

for ( i = 0; i < n; i++ )
x[ i ] = i;

free( x );
}


But how can we allocate a dynimic mem for an array
In the code above it is *x but what can we do if x is decleared as a array?

This is legal even with C89. Of course 'x' isn't a real array but just
a pointer to some memory that can hold the number of integers you need.
And in many places 'x' can be treated like a real array, but there are
subtle differences, e.g. sizeof x is not the amount of memory it's
pointing to but the size of a pointer. And, of course, you must free()
the memory you allocated when you don't need it anymore.

Regards, Jens


Thanks for all the answers
Nov 13 '05 #5

P: n/a
da***********@yahoo.com wrote:
Je***********@physik.fu-berlin.de wrote in message news:<bl************@uni-berlin.de>...
On the other had you have dynamically allocated arrays:

void daa( int n )
{
int *x;
int i;

x = malloc( n * sizepf *x );
if ( x == NULL )
{
fprintf( stderr, "Can't allocate memory\n" );
exit( EXIT_FAILURE );
}

for ( i = 0; i < n; i++ )
x[ i ] = i;

free( x );
}
But how can we allocate a dynimic mem for an array
In the code above it is *x but what can we do if x is decleared as a array?


You can't change the length of an array once you have created it. If
you need dynamically resizeable arrays you must work with pointers and
use malloc()/realloc() to change the amount of memory they point to.
If you look up how other languages implement arrays of non-fixed
length (e.g. in Perl) you will find that they often are written in C
and actually use malloc()/realloc() to achieve this effect.

Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring
Nov 13 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.